root/src/filemanager/boxes.c

/* [previous][next][first][last][top][bottom][index][help]  */

DEFINITIONS

This source file includes following definitions.
  1. configure_callback
  2. skin_apply
  3. skin_name_to_label
  4. skin_dlg_callback
  5. sel_skin_button
  6. appearance_box_callback
  7. panel_listing_callback
  8. sel_charset_button
  9. tree_callback
  10. confvfs_callback
  11. jobs_fill_listbox
  12. task_cb
  13. configure_box
  14. appearance_box
  15. panel_options_box
  16. panel_listing_box
  17. sort_box
  18. confirm_box
  19. display_bits_box
  20. display_bits_box
  21. tree_box
  22. configure_vfs_box
  23. cd_box
  24. symlink_box
  25. jobs_box

   1 /*
   2    Some misc dialog boxes for the program.
   3 
   4    Copyright (C) 1994-2025
   5    Free Software Foundation, Inc.
   6 
   7    Written by:
   8    Miguel de Icaza, 1994, 1995
   9    Jakub Jelinek, 1995
  10    Andrew Borodin <aborodin@vmail.ru>, 2009-2022
  11 
  12    This file is part of the Midnight Commander.
  13 
  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.
  18 
  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.
  23 
  24    You should have received a copy of the GNU General Public License
  25    along with this program.  If not, see <https://www.gnu.org/licenses/>.
  26  */
  27 
  28 /** \file boxes.c
  29  *  \brief Source: Some misc dialog boxes for the program
  30  */
  31 
  32 #include <config.h>
  33 
  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>
  41 
  42 #include "lib/global.h"
  43 
  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"
  50 
  51 #include "lib/vfs/vfs.h"
  52 #ifdef ENABLE_VFS_FTP
  53 #include "src/vfs/ftpfs/ftpfs.h"
  54 #endif
  55 
  56 #include "lib/util.h"  // Q_()
  57 #include "lib/widget.h"
  58 
  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
  65 
  66 #ifdef HAVE_CHARSET
  67 #include "lib/charsets.h"
  68 #include "src/selcodepage.h"
  69 #endif
  70 
  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"
  76 
  77 #include "boxes.h"
  78 
  79 /*** global variables ****************************************************************************/
  80 
  81 /*** file scope macro definitions ****************************************************************/
  82 
  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
  88 
  89 /*** file scope type declarations ****************************************************************/
  90 
  91 /*** forward declarations (file scope functions) *************************************************/
  92 
  93 /*** file scope variables ************************************************************************/
  94 
  95 static unsigned long configure_old_esc_mode_id, configure_time_out_id;
  96 
  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;
 101 
 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;
 105 
 106 #ifdef HAVE_CHARSET
 107 static int new_display_codepage;
 108 #endif
 109 
 110 #if defined(ENABLE_VFS) && defined(ENABLE_VFS_FTP)
 111 static unsigned long ftpfs_always_use_proxy_id, ftpfs_proxy_host_id;
 112 #endif
 113 
 114 static GPtrArray *skin_names;
 115 static gchar *current_skin_name;
 116 
 117 #ifdef ENABLE_BACKGROUND
 118 static WListbox *bg_list = NULL;
 119 #endif
 120 
 121 static unsigned long shadows_id;
 122 
 123 /* --------------------------------------------------------------------------------------------- */
 124 /*** file scope functions ************************************************************************/
 125 /* --------------------------------------------------------------------------------------------- */
 126 
 127 static cb_ret_t
 128 configure_callback (Widget *w, Widget *sender, widget_msg_t msg, int parm, void *data)
     /* [previous][next][first][last][top][bottom][index][help]  */
 129 {
 130     switch (msg)
 131     {
 132     case MSG_NOTIFY:
 133         // message from "Single press" checkbutton
 134         if (sender != NULL && sender->id == configure_old_esc_mode_id)
 135         {
 136             const gboolean not_single = !CHECK (sender)->state;
 137             Widget *ww;
 138 
 139             // input line
 140             ww = widget_find_by_id (w, configure_time_out_id);
 141             widget_disable (ww, not_single);
 142 
 143             return MSG_HANDLED;
 144         }
 145         return MSG_NOT_HANDLED;
 146 
 147     default:
 148         return dlg_default_callback (w, sender, msg, parm, data);
 149     }
 150 }
 151 
 152 /* --------------------------------------------------------------------------------------------- */
 153 
 154 static void
 155 skin_apply (const gchar *skin_override)
     /* [previous][next][first][last][top][bottom][index][help]  */
 156 {
 157     GError *mcerror = NULL;
 158 
 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 ();
 170 
 171     mc_error_message (&mcerror, NULL);
 172 }
 173 
 174 /* --------------------------------------------------------------------------------------------- */
 175 
 176 static const gchar *
 177 skin_name_to_label (const gchar *name)
     /* [previous][next][first][last][top][bottom][index][help]  */
 178 {
 179     if (strcmp (name, "default") == 0)
 180         return _ ("< Default >");
 181     return name;
 182 }
 183 
 184 /* --------------------------------------------------------------------------------------------- */
 185 
 186 static cb_ret_t
 187 skin_dlg_callback (Widget *w, Widget *sender, widget_msg_t msg, int parm, void *data)
     /* [previous][next][first][last][top][bottom][index][help]  */
 188 {
 189     switch (msg)
 190     {
 191     case MSG_RESIZE:
 192     {
 193         WDialog *d = DIALOG (w);
 194         const WRect *wd = &WIDGET (d->data.p)->rect;
 195         WRect r = w->rect;
 196 
 197         r.y = wd->y + (wd->lines - r.lines) / 2;
 198         r.x = wd->x + wd->cols / 2;
 199 
 200         return dlg_default_callback (w, NULL, MSG_RESIZE, 0, &r);
 201     }
 202 
 203     default:
 204         return dlg_default_callback (w, sender, msg, parm, data);
 205     }
 206 }
 207 
 208 /* --------------------------------------------------------------------------------------------- */
 209 
 210 static int
 211 sel_skin_button (WButton *button, int action)
     /* [previous][next][first][last][top][bottom][index][help]  */
 212 {
 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;
 219 
 220     (void) action;
 221 
 222     skin_dlg = dlg_create (TRUE, 0, 0, 13, 24, WPOS_KEEP_DEFAULT, TRUE, dialog_colors,
 223                            skin_dlg_callback, NULL, "[Appearance]", _ ("Skins"));
 224     // use Appearance dialog for positioning
 225     skin_dlg->data.p = WIDGET (button)->owner;
 226 
 227     // set dialog location before all
 228     send_message (skin_dlg, NULL, MSG_RESIZE, 0, NULL);
 229 
 230     skin_list = listbox_new (1, 1, 11, 22, FALSE, NULL);
 231     skin_name = "default";
 232     listbox_add_item (skin_list, LISTBOX_APPEND_AT_END, 0, skin_name_to_label (skin_name),
 233                       (void *) skin_name, FALSE);
 234 
 235     if (strcmp (skin_name, current_skin_name) == 0)
 236         listbox_set_current (skin_list, 0);
 237 
 238     for (i = 0; i < skin_names->len; i++)
 239     {
 240         skin_name = g_ptr_array_index (skin_names, i);
 241         if (strcmp (skin_name, "default") != 0)
 242         {
 243             listbox_add_item (skin_list, LISTBOX_APPEND_AT_END, 0, skin_name_to_label (skin_name),
 244                               (void *) skin_name, FALSE);
 245             if (strcmp (skin_name, current_skin_name) == 0)
 246                 listbox_set_current (skin_list, pos);
 247             pos++;
 248         }
 249     }
 250 
 251     // make list stick to all sides of dialog, effectively make it be resized with dialog
 252     group_add_widget_autopos (GROUP (skin_dlg), skin_list, WPOS_KEEP_ALL, NULL);
 253 
 254     result = dlg_run (skin_dlg);
 255     if (result == B_ENTER)
 256     {
 257         gchar *skin_label;
 258 
 259         listbox_get_current (skin_list, &skin_label, (void **) &skin_name);
 260         g_free (current_skin_name);
 261         current_skin_name = g_strdup (skin_name);
 262         skin_apply (skin_name);
 263 
 264         button_set_text (button, str_fit_to_term (skin_label, 20, J_LEFT_FIT));
 265     }
 266     widget_destroy (WIDGET (skin_dlg));
 267 
 268     return 0;
 269 }
 270 
 271 /* --------------------------------------------------------------------------------------------- */
 272 
 273 static cb_ret_t
 274 appearance_box_callback (Widget *w, Widget *sender, widget_msg_t msg, int parm, void *data)
     /* [previous][next][first][last][top][bottom][index][help]  */
 275 {
 276     switch (msg)
 277     {
 278     case MSG_INIT:
 279 #ifdef ENABLE_SHADOWS
 280         if (!tty_use_colors ())
 281 #endif
 282         {
 283             Widget *shadow;
 284 
 285             shadow = widget_find_by_id (w, shadows_id);
 286             CHECK (shadow)->state = FALSE;
 287             widget_disable (shadow, TRUE);
 288         }
 289         return MSG_HANDLED;
 290 
 291     case MSG_NOTIFY:
 292         if (sender != NULL && sender->id == shadows_id)
 293         {
 294             mc_global.tty.shadows = CHECK (sender)->state;
 295             repaint_screen ();
 296             return MSG_HANDLED;
 297         }
 298         return MSG_NOT_HANDLED;
 299 
 300     default:
 301         return dlg_default_callback (w, sender, msg, parm, data);
 302     }
 303 }
 304 
 305 /* --------------------------------------------------------------------------------------------- */
 306 
 307 static cb_ret_t
 308 panel_listing_callback (Widget *w, Widget *sender, widget_msg_t msg, int parm, void *data)
     /* [previous][next][first][last][top][bottom][index][help]  */
 309 {
 310     switch (msg)
 311     {
 312     case MSG_NOTIFY:
 313         if (sender != NULL && sender->id == panel_list_formats_id)
 314         {
 315             WCheck *ch;
 316             WInput *in1, *in2, *in3;
 317 
 318             in1 = INPUT (widget_find_by_id (w, panel_user_format_id));
 319             in2 = INPUT (widget_find_by_id (w, panel_brief_cols_id));
 320             ch = CHECK (widget_find_by_id (w, user_mini_status_id));
 321             in3 = INPUT (widget_find_by_id (w, mini_user_format_id));
 322 
 323             if (!ch->state)
 324                 input_assign_text (in3, status_format[RADIO (sender)->sel]);
 325             input_update (in1, FALSE);
 326             input_update (in2, FALSE);
 327             input_update (in3, FALSE);
 328             widget_disable (WIDGET (in1), RADIO (sender)->sel != panel_list_user_idx);
 329             widget_disable (WIDGET (in2), RADIO (sender)->sel != panel_list_brief_idx);
 330             return MSG_HANDLED;
 331         }
 332 
 333         if (sender != NULL && sender->id == user_mini_status_id)
 334         {
 335             WInput *in;
 336 
 337             in = INPUT (widget_find_by_id (w, mini_user_format_id));
 338 
 339             if (CHECK (sender)->state)
 340             {
 341                 widget_disable (WIDGET (in), FALSE);
 342                 input_assign_text (in, status_format[3]);
 343             }
 344             else
 345             {
 346                 WRadio *r;
 347 
 348                 r = RADIO (widget_find_by_id (w, panel_list_formats_id));
 349                 widget_disable (WIDGET (in), TRUE);
 350                 input_assign_text (in, status_format[r->sel]);
 351             }
 352             // input_update (in, FALSE);
 353             return MSG_HANDLED;
 354         }
 355 
 356         return MSG_NOT_HANDLED;
 357 
 358     default:
 359         return dlg_default_callback (w, sender, msg, parm, data);
 360     }
 361 }
 362 
 363 /* --------------------------------------------------------------------------------------------- */
 364 
 365 #ifdef HAVE_CHARSET
 366 static int
 367 sel_charset_button (WButton *button, int action)
     /* [previous][next][first][last][top][bottom][index][help]  */
 368 {
 369     int new_dcp;
 370 
 371     (void) action;
 372 
 373     new_dcp = select_charset (-1, -1, new_display_codepage, TRUE);
 374 
 375     if (new_dcp != SELECT_CHARSET_CANCEL)
 376     {
 377         const char *cpname;
 378 
 379         new_display_codepage = new_dcp;
 380         cpname = (new_display_codepage == SELECT_CHARSET_OTHER_8BIT)
 381             ? _ ("Other 8 bit")
 382             : ((codepage_desc *) g_ptr_array_index (codepages, new_display_codepage))->name;
 383         if (cpname != NULL)
 384             mc_global.utf8_display = str_isutf8 (cpname);
 385         else
 386             cpname = _ ("7-bit ASCII");  // FIXME
 387 
 388         button_set_text (button, cpname);
 389         widget_draw (WIDGET (WIDGET (button)->owner));
 390     }
 391 
 392     return 0;
 393 }
 394 #endif
 395 
 396 /* --------------------------------------------------------------------------------------------- */
 397 
 398 static cb_ret_t
 399 tree_callback (Widget *w, Widget *sender, widget_msg_t msg, int parm, void *data)
     /* [previous][next][first][last][top][bottom][index][help]  */
 400 {
 401     WDialog *h = DIALOG (w);
 402 
 403     switch (msg)
 404     {
 405     case MSG_RESIZE:
 406     {
 407         WRect r = w->rect;
 408         Widget *bar;
 409 
 410         r.lines = LINES - 9;
 411         r.cols = COLS - 20;
 412         dlg_default_callback (w, NULL, MSG_RESIZE, 0, &r);
 413 
 414         bar = WIDGET (buttonbar_find (h));
 415         bar->rect.x = 0;
 416         bar->rect.y = LINES - 1;
 417         return MSG_HANDLED;
 418     }
 419 
 420     case MSG_ACTION:
 421         return send_message (find_tree (h), NULL, MSG_ACTION, parm, NULL);
 422 
 423     default:
 424         return dlg_default_callback (w, sender, msg, parm, data);
 425     }
 426 }
 427 
 428 /* --------------------------------------------------------------------------------------------- */
 429 
 430 #if defined(ENABLE_VFS) && defined(ENABLE_VFS_FTP)
 431 static cb_ret_t
 432 confvfs_callback (Widget *w, Widget *sender, widget_msg_t msg, int parm, void *data)
     /* [previous][next][first][last][top][bottom][index][help]  */
 433 {
 434     switch (msg)
 435     {
 436     case MSG_NOTIFY:
 437         // message from "Always use ftp proxy" checkbutton
 438         if (sender != NULL && sender->id == ftpfs_always_use_proxy_id)
 439         {
 440             const gboolean not_use = !CHECK (sender)->state;
 441             Widget *wi;
 442 
 443             // input
 444             wi = widget_find_by_id (w, ftpfs_proxy_host_id);
 445             widget_disable (wi, not_use);
 446             return MSG_HANDLED;
 447         }
 448         return MSG_NOT_HANDLED;
 449 
 450     default:
 451         return dlg_default_callback (w, sender, msg, parm, data);
 452     }
 453 }
 454 #endif
 455 
 456 /* --------------------------------------------------------------------------------------------- */
 457 
 458 #ifdef ENABLE_BACKGROUND
 459 static void
 460 jobs_fill_listbox (WListbox *list)
     /* [previous][next][first][last][top][bottom][index][help]  */
 461 {
 462     static const char *state_str[2] = { "", "" };
 463     TaskList *tl;
 464 
 465     if (state_str[0][0] == '\0')
 466     {
 467         state_str[0] = _ ("Running");
 468         state_str[1] = _ ("Stopped");
 469     }
 470 
 471     for (tl = task_list; tl != NULL; tl = tl->next)
 472     {
 473         char *s;
 474 
 475         s = g_strconcat (state_str[tl->state], " ", tl->info, (char *) NULL);
 476         listbox_add_item_take (list, LISTBOX_APPEND_AT_END, 0, s, (void *) tl, FALSE);
 477     }
 478 }
 479 
 480 /* --------------------------------------------------------------------------------------------- */
 481 
 482 static int
 483 task_cb (WButton *button, int action)
     /* [previous][next][first][last][top][bottom][index][help]  */
 484 {
 485     TaskList *tl;
 486     int sig = 0;
 487 
 488     (void) button;
 489 
 490     if (bg_list->list == NULL)
 491         return 0;
 492 
 493     // Get this instance information
 494     listbox_get_current (bg_list, NULL, (void **) &tl);
 495 
 496 #ifdef SIGTSTP
 497     if (action == B_STOP)
 498     {
 499         sig = SIGSTOP;
 500         tl->state = Task_Stopped;
 501     }
 502     else if (action == B_RESUME)
 503     {
 504         sig = SIGCONT;
 505         tl->state = Task_Running;
 506     }
 507     else
 508 #endif
 509         if (action == B_KILL)
 510         sig = SIGKILL;
 511 
 512     if (sig == SIGKILL)
 513         unregister_task_running (tl->pid, tl->fd);
 514 
 515     kill (tl->pid, sig);
 516     listbox_remove_list (bg_list);
 517     jobs_fill_listbox (bg_list);
 518 
 519     // This can be optimized to just redraw this widget :-)
 520     widget_draw (WIDGET (WIDGET (button)->owner));
 521 
 522     return 0;
 523 }
 524 #endif
 525 
 526 /* --------------------------------------------------------------------------------------------- */
 527 /*** public functions ****************************************************************************/
 528 /* --------------------------------------------------------------------------------------------- */
 529 
 530 void
 531 configure_box (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
 532 {
 533     const char *pause_options[] = {
 534         N_ ("&Never"),
 535         N_ ("On dum&b terminals"),
 536         N_ ("Alwa&ys"),
 537     };
 538     const int pause_options_num = G_N_ELEMENTS (pause_options);
 539 
 540     {
 541         char time_out[BUF_TINY] = "";
 542         char *time_out_new = NULL;
 543 
 544         quick_widget_t quick_widgets[] = {
 545             // clang-format off
 546             QUICK_START_COLUMNS,
 547                 QUICK_START_GROUPBOX (N_ ("File operations")),
 548                     QUICK_CHECKBOX (N_ ("&Verbose operation"), &verbose, NULL),
 549                     QUICK_CHECKBOX (N_ ("Compute tota&ls"), &file_op_compute_totals, NULL),
 550                     QUICK_CHECKBOX (N_ ("Classic pro&gressbar"), &classic_progressbar, NULL),
 551                     QUICK_CHECKBOX (N_ ("Mkdi&r autoname"), &auto_fill_mkdir_name, NULL),
 552                     QUICK_CHECKBOX (N_ ("&Preallocate space"), &mc_global.vfs.preallocate_space,
 553                                     NULL),
 554                 QUICK_STOP_GROUPBOX,
 555                 QUICK_START_GROUPBOX (N_ ("Esc key mode")),
 556                     QUICK_CHECKBOX (N_ ("S&ingle press"), &old_esc_mode, &configure_old_esc_mode_id),
 557                     QUICK_LABELED_INPUT (N_ ("Timeout:"), input_label_left,
 558                                          (const char *) time_out, MC_HISTORY_ESC_TIMEOUT,
 559                                          &time_out_new, &configure_time_out_id, FALSE, FALSE,
 560                                          INPUT_COMPLETE_NONE),
 561                 QUICK_STOP_GROUPBOX,
 562                 QUICK_START_GROUPBOX (N_ ("Pause after run")),
 563                     QUICK_RADIO (pause_options_num, pause_options, &pause_after_run, NULL),
 564                 QUICK_STOP_GROUPBOX,
 565             QUICK_NEXT_COLUMN,
 566                 QUICK_START_GROUPBOX (N_ ("Other options")),
 567                     QUICK_CHECKBOX (N_ ("Use internal edi&t"), &use_internal_edit, NULL),
 568                     QUICK_CHECKBOX (N_ ("Use internal vie&w"), &use_internal_view, NULL),
 569                     QUICK_CHECKBOX (N_ ("A&sk new file name"),
 570                                     &editor_ask_filename_before_edit, NULL),
 571                     QUICK_CHECKBOX (N_ ("Auto m&enus"), &auto_menu, NULL),
 572                     QUICK_CHECKBOX (N_ ("&Drop down menus"), &drop_menus, NULL),
 573                     QUICK_CHECKBOX (N_ ("S&hell patterns"), &easy_patterns, NULL),
 574                     QUICK_CHECKBOX (N_ ("Co&mplete: show all"),
 575                                     &mc_global.widget.show_all_if_ambiguous, NULL),
 576                     QUICK_CHECKBOX (N_ ("Rotating d&ash"), &nice_rotating_dash, NULL),
 577                     QUICK_CHECKBOX (N_ ("Cd follows lin&ks"), &mc_global.vfs.cd_symlinks, NULL),
 578                     QUICK_CHECKBOX (N_ ("Sa&fe delete"), &safe_delete, NULL),
 579                     QUICK_CHECKBOX (N_ ("Safe overwrite"), &safe_overwrite, NULL),       // w/o hotkey
 580                     QUICK_CHECKBOX (N_ ("A&uto save setup"), &auto_save_setup, NULL),
 581                     QUICK_SEPARATOR (FALSE),
 582                     QUICK_SEPARATOR (FALSE),
 583                 QUICK_STOP_GROUPBOX,
 584             QUICK_STOP_COLUMNS,
 585             QUICK_BUTTONS_OK_CANCEL,
 586             QUICK_END,
 587             // clang-format on
 588         };
 589 
 590         WRect r = { -1, -1, 0, 60 };
 591 
 592         quick_dialog_t qdlg = {
 593             .rect = r,
 594             .title = N_ ("Configure options"),
 595             .help = "[Configuration]",
 596             .widgets = quick_widgets,
 597             .callback = configure_callback,
 598             .mouse_callback = NULL,
 599         };
 600 
 601         g_snprintf (time_out, sizeof (time_out), "%d", old_esc_mode_timeout);
 602 
 603 #ifndef USE_INTERNAL_EDIT
 604         quick_widgets[17].state = WST_DISABLED;
 605 #endif
 606 
 607         if (!old_esc_mode)
 608             quick_widgets[10].state = quick_widgets[11].state = WST_DISABLED;
 609 
 610 #ifndef HAVE_POSIX_FALLOCATE
 611         mc_global.vfs.preallocate_space = FALSE;
 612         quick_widgets[7].state = WST_DISABLED;
 613 #endif
 614 
 615         if (quick_dialog (&qdlg) == B_ENTER)
 616         {
 617             if (time_out_new[0] == '\0')
 618                 old_esc_mode_timeout = 0;
 619             else
 620                 old_esc_mode_timeout = atoi (time_out_new);
 621         }
 622 
 623         g_free (time_out_new);
 624     }
 625 }
 626 
 627 /* --------------------------------------------------------------------------------------------- */
 628 
 629 void
 630 appearance_box (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
 631 {
 632     gboolean shadows = mc_global.tty.shadows;
 633 
 634     current_skin_name = g_strdup (mc_skin__default.name);
 635     skin_names = mc_skin_list ();
 636 
 637     {
 638         quick_widget_t quick_widgets[] = {
 639             // clang-format 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,
 644                               J_LEFT_FIT), 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             // clang-format on
 651         };
 652 
 653         WRect r = { -1, -1, 0, 54 };
 654 
 655         quick_dialog_t qdlg = {
 656             .rect = r,
 657             .title = N_ ("Appearance"),
 658             .help = "[Appearance]",
 659             .widgets = quick_widgets,
 660             .callback = appearance_box_callback,
 661             .mouse_callback = NULL,
 662         };
 663 
 664         if (quick_dialog (&qdlg) == B_ENTER)
 665             mc_config_set_string (mc_global.main_config, CONFIG_APP_SECTION, "skin",
 666                                   current_skin_name);
 667         else
 668         {
 669             skin_apply (NULL);
 670             mc_global.tty.shadows = shadows;
 671         }
 672     }
 673 
 674     g_free (current_skin_name);
 675     g_ptr_array_free (skin_names, TRUE);
 676 }
 677 
 678 /* --------------------------------------------------------------------------------------------- */
 679 
 680 void
 681 panel_options_box (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
 682 {
 683     gboolean simple_swap;
 684 
 685     simple_swap =
 686         mc_config_get_bool (mc_global.main_config, CONFIG_PANELS_SECTION, "simple_swap", FALSE);
 687     {
 688         const char *qsearch_options[] = {
 689             N_ ("Case &insensitive"),
 690             N_ ("Cas&e sensitive"),
 691             N_ ("Use panel sort mo&de"),
 692         };
 693 
 694         quick_widget_t quick_widgets[] = {
 695             // clang-format off
 696             QUICK_START_COLUMNS,
 697                 QUICK_START_GROUPBOX (N_ ("Main options")),
 698                     QUICK_CHECKBOX (N_ ("Show mi&ni-status"), &panels_options.show_mini_info, NULL),
 699                     QUICK_CHECKBOX (N_ ("Use SI si&ze units"), &panels_options.kilobyte_si, NULL),
 700                     QUICK_CHECKBOX (N_ ("Mi&x all files"), &panels_options.mix_all_files, NULL),
 701                     QUICK_CHECKBOX (N_ ("Show &backup files"), &panels_options.show_backups, NULL),
 702                     QUICK_CHECKBOX (N_ ("Show &hidden files"), &panels_options.show_dot_files, NULL),
 703                     QUICK_CHECKBOX (N_ ("&Fast dir reload"), &panels_options.fast_reload, NULL),
 704                     QUICK_CHECKBOX (N_ ("Ma&rk moves down"), &panels_options.mark_moves_down, NULL),
 705                     QUICK_CHECKBOX (N_ ("Re&verse files only"), &panels_options.reverse_files_only,
 706                                     NULL),
 707                     QUICK_CHECKBOX (N_ ("Simple s&wap"), &simple_swap, NULL),
 708                     QUICK_CHECKBOX (N_ ("A&uto save panels setup"), &panels_options.auto_save_setup,
 709                                     NULL),
 710                     QUICK_SEPARATOR (FALSE),
 711                     QUICK_SEPARATOR (FALSE),
 712                     QUICK_SEPARATOR (FALSE),
 713                 QUICK_STOP_GROUPBOX,
 714             QUICK_NEXT_COLUMN,
 715                 QUICK_START_GROUPBOX (N_ ("Navigation")),
 716                     QUICK_CHECKBOX (N_ ("L&ynx-like motion"), &panels_options.navigate_with_arrows,
 717                                     NULL),
 718                     QUICK_CHECKBOX (N_ ("Pa&ge scrolling"), &panels_options.scroll_pages, NULL),
 719                     QUICK_CHECKBOX (N_ ("Center &scrolling"), &panels_options.scroll_center, NULL),
 720                     QUICK_CHECKBOX (N_ ("&Mouse page scrolling"), &panels_options.mouse_move_pages,
 721                                     NULL),
 722                 QUICK_STOP_GROUPBOX,
 723                 QUICK_START_GROUPBOX (N_ ("File highlight")),
 724                     QUICK_CHECKBOX (N_ ("File &types"), &panels_options.filetype_mode, NULL),
 725                     QUICK_CHECKBOX (N_ ("&Permissions"), &panels_options.permission_mode, NULL),
 726                 QUICK_STOP_GROUPBOX,
 727                 QUICK_START_GROUPBOX (N_ ("Quick search")),
 728                     QUICK_RADIO (QSEARCH_NUM, qsearch_options, (int *) &panels_options.qsearch_mode,
 729                                  NULL),
 730                 QUICK_STOP_GROUPBOX,
 731             QUICK_STOP_COLUMNS,
 732             QUICK_BUTTONS_OK_CANCEL,
 733             QUICK_END,
 734             // clang-format on
 735         };
 736 
 737         WRect r = { -1, -1, 0, 60 };
 738 
 739         quick_dialog_t qdlg = {
 740             .rect = r,
 741             .title = N_ ("Panel options"),
 742             .help = "[Panel options]",
 743             .widgets = quick_widgets,
 744             .callback = NULL,
 745             .mouse_callback = NULL,
 746         };
 747 
 748         if (quick_dialog (&qdlg) != B_ENTER)
 749             return;
 750     }
 751 
 752     mc_config_set_bool (mc_global.main_config, CONFIG_PANELS_SECTION, "simple_swap", simple_swap);
 753 
 754     if (!panels_options.fast_reload_msg_shown && panels_options.fast_reload)
 755     {
 756         message (D_NORMAL, _ ("Information"),
 757                  _ ("Using the fast reload option may not reflect the exact\n"
 758                     "directory contents. In this case you'll need to do a\n"
 759                     "manual reload of the directory. See the man page for\n"
 760                     "the details."));
 761         panels_options.fast_reload_msg_shown = TRUE;
 762     }
 763 
 764     update_panels (UP_RELOAD, UP_KEEPSEL);
 765 }
 766 
 767 /* --------------------------------------------------------------------------------------------- */
 768 
 769 /* return list type */
 770 int
 771 panel_listing_box (WPanel *panel, int num, char **userp, char **minip, gboolean *use_msformat,
     /* [previous][next][first][last][top][bottom][index][help]  */
 772                    int *brief_cols)
 773 {
 774     int result = -1;
 775     const char *p = NULL;
 776 
 777     if (panel == NULL)
 778     {
 779         p = get_nth_panel_name (num);
 780         panel = panel_empty_new (p);
 781     }
 782 
 783     {
 784         gboolean user_mini_status;
 785         char panel_brief_cols_in[BUF_TINY];
 786         char *panel_brief_cols_out = NULL;
 787         char *panel_user_format = NULL;
 788         char *mini_user_format = NULL;
 789 
 790         // Controls whether the array strings have been translated
 791         const char *list_formats[LIST_FORMATS] = {
 792             N_ ("&Full file list"),
 793             N_ ("&Brief file list:"),
 794             N_ ("&Long file list"),
 795             N_ ("&User defined:"),
 796         };
 797 
 798         quick_widget_t quick_widgets[] = {
 799             // clang-format off
 800             QUICK_START_COLUMNS,
 801                 QUICK_RADIO (LIST_FORMATS, list_formats, &result, &panel_list_formats_id),
 802             QUICK_NEXT_COLUMN,
 803                 QUICK_SEPARATOR (FALSE),
 804                 QUICK_LABELED_INPUT (N_ ("columns"), input_label_right, panel_brief_cols_in,
 805                                      "panel-brief-cols-input", &panel_brief_cols_out,
 806                                      &panel_brief_cols_id, FALSE, FALSE, INPUT_COMPLETE_NONE),
 807             QUICK_STOP_COLUMNS,
 808             QUICK_INPUT (panel->user_format, "user-fmt-input", &panel_user_format,
 809                          &panel_user_format_id, FALSE, FALSE, INPUT_COMPLETE_NONE),
 810             QUICK_SEPARATOR (TRUE),
 811             QUICK_CHECKBOX (N_ ("User &mini status"), &user_mini_status, &user_mini_status_id),
 812             QUICK_INPUT (panel->user_status_format[panel->list_format], "mini_input",
 813                          &mini_user_format, &mini_user_format_id, FALSE, FALSE, INPUT_COMPLETE_NONE),
 814             QUICK_BUTTONS_OK_CANCEL,
 815             QUICK_END,
 816             // clang-format on
 817         };
 818 
 819         WRect r = { -1, -1, 0, 48 };
 820 
 821         quick_dialog_t qdlg = {
 822             .rect = r,
 823             .title = N_ ("Listing format"),
 824             .help = "[Listing Format...]",
 825             .widgets = quick_widgets,
 826             .callback = panel_listing_callback,
 827             .mouse_callback = NULL,
 828         };
 829 
 830         user_mini_status = panel->user_mini_status;
 831         result = panel->list_format;
 832         status_format = panel->user_status_format;
 833 
 834         g_snprintf (panel_brief_cols_in, sizeof (panel_brief_cols_in), "%d", panel->brief_cols);
 835 
 836         if ((int) panel->list_format != panel_list_brief_idx)
 837             quick_widgets[4].state = WST_DISABLED;
 838 
 839         if ((int) panel->list_format != panel_list_user_idx)
 840             quick_widgets[6].state = WST_DISABLED;
 841 
 842         if (!user_mini_status)
 843             quick_widgets[9].state = WST_DISABLED;
 844 
 845         if (quick_dialog (&qdlg) == B_CANCEL)
 846             result = -1;
 847         else
 848         {
 849             int cols;
 850             char *error = NULL;
 851 
 852             *userp = panel_user_format;
 853             *minip = mini_user_format;
 854             *use_msformat = user_mini_status;
 855 
 856             cols = strtol (panel_brief_cols_out, &error, 10);
 857             if (*error == '\0')
 858                 *brief_cols = cols;
 859             else
 860                 *brief_cols = panel->brief_cols;
 861 
 862             g_free (panel_brief_cols_out);
 863         }
 864     }
 865 
 866     if (p != NULL)
 867     {
 868         int i;
 869 
 870         g_free (panel->user_format);
 871         for (i = 0; i < LIST_FORMATS; i++)
 872             g_free (panel->user_status_format[i]);
 873         g_free (panel);
 874     }
 875 
 876     return result;
 877 }
 878 
 879 /* --------------------------------------------------------------------------------------------- */
 880 
 881 const panel_field_t *
 882 sort_box (dir_sort_options_t *op, const panel_field_t *sort_field)
     /* [previous][next][first][last][top][bottom][index][help]  */
 883 {
 884     char **sort_orders_names;
 885     gsize i;
 886     gsize sort_names_num = 0;
 887     int sort_idx = 0;
 888     const panel_field_t *result = NULL;
 889 
 890     sort_orders_names = panel_get_sortable_fields (&sort_names_num);
 891 
 892     for (i = 0; i < sort_names_num; i++)
 893         if (strcmp (sort_orders_names[i], _ (sort_field->title_hotkey)) == 0)
 894         {
 895             sort_idx = i;
 896             break;
 897         }
 898 
 899     {
 900         quick_widget_t quick_widgets[] = {
 901             // clang-format off
 902             QUICK_START_COLUMNS,
 903                 QUICK_RADIO (sort_names_num, (const char **) sort_orders_names, &sort_idx, NULL),
 904             QUICK_NEXT_COLUMN,
 905                 QUICK_CHECKBOX (N_ ("Executable &first"), &op->exec_first, NULL),
 906                 QUICK_CHECKBOX (N_ ("Cas&e sensitive"), &op->case_sensitive, NULL),
 907                 QUICK_CHECKBOX (N_ ("&Reverse"), &op->reverse, NULL),
 908             QUICK_STOP_COLUMNS,
 909             QUICK_BUTTONS_OK_CANCEL,
 910             QUICK_END,
 911             // clang-format on
 912         };
 913 
 914         WRect r = { -1, -1, 0, 40 };
 915 
 916         quick_dialog_t qdlg = {
 917             .rect = r,
 918             .title = N_ ("Sort order"),
 919             .help = "[Sort Order...]",
 920             .widgets = quick_widgets,
 921             .callback = NULL,
 922             .mouse_callback = NULL,
 923         };
 924 
 925         if (quick_dialog (&qdlg) != B_CANCEL)
 926             result = panel_get_field_by_title_hotkey (sort_orders_names[sort_idx]);
 927 
 928         if (result == NULL)
 929             result = sort_field;
 930     }
 931 
 932     g_strfreev (sort_orders_names);
 933 
 934     return result;
 935 }
 936 
 937 /* --------------------------------------------------------------------------------------------- */
 938 
 939 void
 940 confirm_box (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
 941 {
 942     quick_widget_t quick_widgets[] = {
 943         // TRANSLATORS: no need to translate 'Confirmation', it's just a context prefix
 944         QUICK_CHECKBOX (Q_ ("Confirmation|&Delete"), &confirm_delete, NULL),
 945         QUICK_CHECKBOX (Q_ ("Confirmation|O&verwrite"), &confirm_overwrite, NULL),
 946         QUICK_CHECKBOX (Q_ ("Confirmation|&Execute"), &confirm_execute, NULL),
 947         QUICK_CHECKBOX (Q_ ("Confirmation|E&xit"), &confirm_exit, NULL),
 948         QUICK_CHECKBOX (Q_ ("Confirmation|Di&rectory hotlist delete"),
 949                         &confirm_directory_hotlist_delete, NULL),
 950         QUICK_CHECKBOX (Q_ ("Confirmation|&History cleanup"),
 951                         &mc_global.widget.confirm_history_cleanup, NULL),
 952         QUICK_BUTTONS_OK_CANCEL,
 953         QUICK_END,
 954     };
 955 
 956     WRect r = { -1, -1, 0, 46 };
 957 
 958     quick_dialog_t qdlg = {
 959         .rect = r,
 960         .title = N_ ("Confirmation"),
 961         .help = "[Confirmation]",
 962         .widgets = quick_widgets,
 963         .callback = NULL,
 964         .mouse_callback = NULL,
 965     };
 966 
 967     (void) quick_dialog (&qdlg);
 968 }
 969 
 970 /* --------------------------------------------------------------------------------------------- */
 971 
 972 #ifndef HAVE_CHARSET
 973 void
 974 display_bits_box (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
 975 {
 976     gboolean new_meta;
 977     int current_mode;
 978 
 979     const char *display_bits_str[] = {
 980         N_ ("&UTF-8 output"),
 981         N_ ("&Full 8 bits output"),
 982         N_ ("&ISO 8859-1"),
 983         N_ ("7 &bits"),
 984     };
 985 
 986     quick_widget_t quick_widgets[] = {
 987         QUICK_RADIO (4, display_bits_str, &current_mode, NULL),
 988         QUICK_SEPARATOR (TRUE),
 989         QUICK_CHECKBOX (N_ ("F&ull 8 bits input"), &new_meta, NULL),
 990         QUICK_BUTTONS_OK_CANCEL,
 991         QUICK_END,
 992     };
 993 
 994     WRect r = { -1, -1, 0, 46 };
 995 
 996     quick_dialog_t qdlg = {
 997         .rect = r,
 998         .title = N_ ("Display bits"),
 999         .help = "[Display bits]",
1000         .widgets = quick_widgets,
1001         .callback = NULL,
1002         .mouse_callback = NULL,
1003     };
1004 
1005     if (mc_global.full_eight_bits)
1006         current_mode = 0;
1007     else if (mc_global.eight_bit_clean)
1008         current_mode = 1;
1009     else
1010         current_mode = 2;
1011 
1012     new_meta = !use_8th_bit_as_meta;
1013 
1014     if (quick_dialog (&qdlg) != B_CANCEL)
1015     {
1016         mc_global.eight_bit_clean = current_mode < 3;
1017         mc_global.full_eight_bits = current_mode < 2;
1018 #ifndef HAVE_SLANG
1019         tty_display_8bit (mc_global.eight_bit_clean);
1020 #else
1021         tty_display_8bit (mc_global.full_eight_bits);
1022 #endif
1023         use_8th_bit_as_meta = !new_meta;
1024     }
1025 }
1026 
1027 /* --------------------------------------------------------------------------------------------- */
1028 #else  // HAVE_CHARSET
1029 
1030 void
1031 display_bits_box (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
1032 {
1033     const char *cpname;
1034 
1035     new_display_codepage = mc_global.display_codepage;
1036 
1037     cpname = (new_display_codepage < 0)
1038         ? _ ("Other 8 bit")
1039         : ((codepage_desc *) g_ptr_array_index (codepages, new_display_codepage))->name;
1040 
1041     {
1042         gboolean new_meta;
1043 
1044         quick_widget_t quick_widgets[] = {
1045             // clang-format off
1046             QUICK_START_COLUMNS,
1047                 QUICK_LABEL (N_ ("Input / display codepage:"), NULL),
1048             QUICK_NEXT_COLUMN,
1049                 QUICK_BUTTON (cpname, B_USER, sel_charset_button, NULL),
1050             QUICK_STOP_COLUMNS,
1051             QUICK_SEPARATOR (TRUE),
1052                 QUICK_CHECKBOX (N_ ("F&ull 8 bits input"), &new_meta, NULL),
1053             QUICK_BUTTONS_OK_CANCEL,
1054             QUICK_END,
1055             // clang-format on
1056         };
1057 
1058         WRect r = { -1, -1, 0, 46 };
1059 
1060         quick_dialog_t qdlg = {
1061             .rect = r,
1062             .title = N_ ("Display bits"),
1063             .help = "[Display bits]",
1064             .widgets = quick_widgets,
1065             .callback = NULL,
1066             .mouse_callback = NULL,
1067         };
1068 
1069         new_meta = !use_8th_bit_as_meta;
1070         application_keypad_mode ();
1071 
1072         if (quick_dialog (&qdlg) == B_ENTER)
1073         {
1074             char *errmsg;
1075 
1076             mc_global.display_codepage = new_display_codepage;
1077 
1078             errmsg = init_translation_table (mc_global.source_codepage, mc_global.display_codepage);
1079             if (errmsg != NULL)
1080             {
1081                 message (D_ERROR, MSG_ERROR, "%s", errmsg);
1082                 g_free (errmsg);
1083             }
1084 
1085 #ifdef HAVE_SLANG
1086             tty_display_8bit (mc_global.display_codepage != 0 && mc_global.display_codepage != 1);
1087 #else
1088             tty_display_8bit (mc_global.display_codepage != 0);
1089 #endif
1090             use_8th_bit_as_meta = !new_meta;
1091 
1092             repaint_screen ();
1093         }
1094     }
1095 }
1096 #endif
1097 
1098 /* --------------------------------------------------------------------------------------------- */
1099 /** Show tree in a box, not on a panel */
1100 
1101 char *
1102 tree_box (const char *current_dir)
     /* [previous][next][first][last][top][bottom][index][help]  */
1103 {
1104     WTree *mytree;
1105     WRect r;
1106     WDialog *dlg;
1107     WGroup *g;
1108     Widget *wd;
1109     char *val = NULL;
1110     WButtonBar *bar;
1111 
1112     (void) current_dir;
1113 
1114     // Create the components
1115     dlg = dlg_create (TRUE, 0, 0, LINES - 9, COLS - 20, WPOS_CENTER, FALSE, dialog_colors,
1116                       tree_callback, NULL, "[Directory Tree]", _ ("Directory tree"));
1117     g = GROUP (dlg);
1118     wd = WIDGET (dlg);
1119 
1120     rect_init (&r, 2, 2, wd->rect.lines - 6, wd->rect.cols - 5);
1121     mytree = tree_new (&r, FALSE);
1122     group_add_widget_autopos (g, mytree, WPOS_KEEP_ALL, NULL);
1123     group_add_widget_autopos (g, hline_new (wd->rect.lines - 4, 1, -1), WPOS_KEEP_BOTTOM, NULL);
1124     bar = buttonbar_new ();
1125     group_add_widget (g, bar);
1126     // restore ButtonBar coordinates after add_widget()
1127     WIDGET (bar)->rect.x = 0;
1128     WIDGET (bar)->rect.y = LINES - 1;
1129 
1130     if (dlg_run (dlg) == B_ENTER)
1131     {
1132         const vfs_path_t *selected_name;
1133 
1134         selected_name = tree_selected_name (mytree);
1135         val = g_strdup (vfs_path_as_str (selected_name));
1136     }
1137 
1138     widget_destroy (wd);
1139     return val;
1140 }
1141 
1142 /* --------------------------------------------------------------------------------------------- */
1143 
1144 #ifdef ENABLE_VFS
1145 void
1146 configure_vfs_box (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
1147 {
1148     char buffer2[BUF_TINY];
1149 #ifdef ENABLE_VFS_FTP
1150     char buffer3[BUF_TINY];
1151 
1152     g_snprintf (buffer3, sizeof (buffer3), "%i", ftpfs_directory_timeout);
1153 #endif
1154 
1155     g_snprintf (buffer2, sizeof (buffer2), "%i", vfs_timeout);
1156 
1157     {
1158         char *ret_timeout;
1159 #ifdef ENABLE_VFS_FTP
1160         char *ret_passwd;
1161         char *ret_ftp_proxy;
1162         char *ret_directory_timeout;
1163 #endif
1164 
1165         quick_widget_t quick_widgets[] = {
1166             QUICK_LABELED_INPUT (N_ ("Timeout for freeing VFSs (sec):"), input_label_left, buffer2,
1167                                  "input-timo-vfs", &ret_timeout, NULL, FALSE, FALSE,
1168                                  INPUT_COMPLETE_NONE),
1169 #ifdef ENABLE_VFS_FTP
1170             QUICK_SEPARATOR (TRUE),
1171             QUICK_LABELED_INPUT (N_ ("FTP anonymous password:"), input_label_left,
1172                                  ftpfs_anonymous_passwd, "input-passwd", &ret_passwd, NULL, FALSE,
1173                                  FALSE, INPUT_COMPLETE_NONE),
1174             QUICK_LABELED_INPUT (N_ ("FTP directory cache timeout (sec):"), input_label_left,
1175                                  buffer3, "input-timeout", &ret_directory_timeout, NULL, FALSE,
1176                                  FALSE, INPUT_COMPLETE_NONE),
1177             QUICK_CHECKBOX (N_ ("&Always use ftp proxy:"), &ftpfs_always_use_proxy,
1178                             &ftpfs_always_use_proxy_id),
1179             QUICK_INPUT (ftpfs_proxy_host, "input-ftp-proxy", &ret_ftp_proxy, &ftpfs_proxy_host_id,
1180                          FALSE, FALSE, INPUT_COMPLETE_HOSTNAMES),
1181             QUICK_CHECKBOX (N_ ("&Use ~/.netrc"), &ftpfs_use_netrc, NULL),
1182             QUICK_CHECKBOX (N_ ("Use &passive mode"), &ftpfs_use_passive_connections, NULL),
1183             QUICK_CHECKBOX (N_ ("Use passive mode over pro&xy"),
1184                             &ftpfs_use_passive_connections_over_proxy, NULL),
1185 #endif
1186             QUICK_BUTTONS_OK_CANCEL,
1187             QUICK_END,
1188         };
1189 
1190         WRect r = { -1, -1, 0, 56 };
1191 
1192         quick_dialog_t qdlg = {
1193             .rect = r,
1194             .title = N_ ("Virtual File System Setting"),
1195             .help = "[Virtual FS]",
1196             .widgets = quick_widgets,
1197 #ifdef ENABLE_VFS_FTP
1198             .callback = confvfs_callback,
1199 #else
1200             .callback = NULL,
1201 #endif
1202             .mouse_callback = NULL,
1203         };
1204 
1205 #ifdef ENABLE_VFS_FTP
1206         if (!ftpfs_always_use_proxy)
1207             quick_widgets[5].state = WST_DISABLED;
1208 #endif
1209 
1210         if (quick_dialog (&qdlg) != B_CANCEL)
1211         {
1212             // cppcheck-suppress uninitvar
1213             if (ret_timeout[0] == '\0')
1214                 vfs_timeout = 0;
1215             else
1216                 vfs_timeout = atoi (ret_timeout);
1217             g_free (ret_timeout);
1218 
1219             if (vfs_timeout < 0 || vfs_timeout > 10000)
1220                 vfs_timeout = 10;
1221 #ifdef ENABLE_VFS_FTP
1222             g_free (ftpfs_anonymous_passwd);
1223             // cppcheck-suppress uninitvar
1224             ftpfs_anonymous_passwd = ret_passwd;
1225             g_free (ftpfs_proxy_host);
1226             // cppcheck-suppress uninitvar
1227             ftpfs_proxy_host = ret_ftp_proxy;
1228             // cppcheck-suppress uninitvar
1229             if (ret_directory_timeout[0] == '\0')
1230                 ftpfs_directory_timeout = 0;
1231             else
1232                 ftpfs_directory_timeout = atoi (ret_directory_timeout);
1233             g_free (ret_directory_timeout);
1234 #endif
1235         }
1236     }
1237 }
1238 
1239 #endif
1240 
1241 /* --------------------------------------------------------------------------------------------- */
1242 
1243 char *
1244 cd_box (const WPanel *panel)
     /* [previous][next][first][last][top][bottom][index][help]  */
1245 {
1246     const Widget *w = CONST_WIDGET (panel);
1247     char *my_str = NULL;
1248 
1249     quick_widget_t quick_widgets[] = {
1250         QUICK_LABELED_INPUT (N_ ("cd"), input_label_left, "", "input", &my_str, NULL, FALSE, TRUE,
1251                              INPUT_COMPLETE_FILENAMES | INPUT_COMPLETE_CD),
1252         QUICK_END,
1253     };
1254 
1255     WRect r = { w->rect.y + w->rect.lines - 6, w->rect.x, 0, w->rect.cols };
1256 
1257     quick_dialog_t qdlg = {
1258         .rect = r,
1259         .title = N_ ("Quick cd"),
1260         .help = "[Quick cd]",
1261         .widgets = quick_widgets,
1262         .callback = NULL,
1263         .mouse_callback = NULL,
1264     };
1265 
1266     return (quick_dialog (&qdlg) != B_CANCEL) ? my_str : NULL;
1267 }
1268 
1269 /* --------------------------------------------------------------------------------------------- */
1270 
1271 void
1272 symlink_box (const vfs_path_t *existing_vpath, const vfs_path_t *new_vpath, char **ret_existing,
     /* [previous][next][first][last][top][bottom][index][help]  */
1273              char **ret_new)
1274 {
1275     quick_widget_t quick_widgets[] = {
1276         QUICK_LABELED_INPUT (N_ ("Existing filename (filename symlink will point to):"),
1277                              input_label_above, vfs_path_as_str (existing_vpath), "input-2",
1278                              ret_existing, NULL, FALSE, FALSE, INPUT_COMPLETE_FILENAMES),
1279         QUICK_SEPARATOR (FALSE),
1280         QUICK_LABELED_INPUT (N_ ("Symbolic link filename:"), input_label_above,
1281                              vfs_path_as_str (new_vpath), "input-1", ret_new, NULL, FALSE, FALSE,
1282                              INPUT_COMPLETE_FILENAMES),
1283         QUICK_BUTTONS_OK_CANCEL,
1284         QUICK_END,
1285     };
1286 
1287     WRect r = { -1, -1, 0, 64 };
1288 
1289     quick_dialog_t qdlg = {
1290         .rect = r,
1291         .title = N_ ("Symbolic link"),
1292         .help = "[File Menu]",
1293         .widgets = quick_widgets,
1294         .callback = NULL,
1295         .mouse_callback = NULL,
1296     };
1297 
1298     if (quick_dialog (&qdlg) == B_CANCEL)
1299     {
1300         *ret_new = NULL;
1301         *ret_existing = NULL;
1302     }
1303 }
1304 
1305 /* --------------------------------------------------------------------------------------------- */
1306 
1307 #ifdef ENABLE_BACKGROUND
1308 void
1309 jobs_box (void)
     /* [previous][next][first][last][top][bottom][index][help]  */
1310 {
1311     struct
1312     {
1313         const char *name;
1314         int flags;
1315         int value;
1316         int len;
1317         bcback_fn callback;
1318     } job_but[] = {
1319         { N_ ("&Stop"), NORMAL_BUTTON, B_STOP, 0, task_cb },
1320         { N_ ("&Resume"), NORMAL_BUTTON, B_RESUME, 0, task_cb },
1321         { N_ ("&Kill"), NORMAL_BUTTON, B_KILL, 0, task_cb },
1322         { N_ ("&OK"), DEFPUSH_BUTTON, B_CANCEL, 0, NULL },
1323     };
1324 
1325     size_t i;
1326     const size_t n_but = G_N_ELEMENTS (job_but);
1327 
1328     WDialog *jobs_dlg;
1329     WGroup *g;
1330     int cols = 60;
1331     int lines = 15;
1332     int x = 0;
1333 
1334     for (i = 0; i < n_but; i++)
1335     {
1336 #ifdef ENABLE_NLS
1337         job_but[i].name = _ (job_but[i].name);
1338 #endif
1339 
1340         job_but[i].len = str_term_width1 (job_but[i].name) + 3;
1341         if (job_but[i].flags == DEFPUSH_BUTTON)
1342             job_but[i].len += 2;
1343         x += job_but[i].len;
1344     }
1345 
1346     x += (int) n_but - 1;
1347     cols = MAX (cols, x + 6);
1348 
1349     jobs_dlg = dlg_create (TRUE, 0, 0, lines, cols, WPOS_CENTER, FALSE, dialog_colors, NULL, NULL,
1350                            "[Background jobs]", _ ("Background jobs"));
1351     g = GROUP (jobs_dlg);
1352 
1353     bg_list = listbox_new (2, 2, lines - 6, cols - 6, FALSE, NULL);
1354     jobs_fill_listbox (bg_list);
1355     group_add_widget (g, bg_list);
1356 
1357     group_add_widget (g, hline_new (lines - 4, -1, -1));
1358 
1359     x = (cols - x) / 2;
1360     for (i = 0; i < n_but; i++)
1361     {
1362         group_add_widget (g,
1363                           button_new (lines - 3, x, job_but[i].value, job_but[i].flags,
1364                                       job_but[i].name, job_but[i].callback));
1365         x += job_but[i].len + 1;
1366     }
1367 
1368     (void) dlg_run (jobs_dlg);
1369     widget_destroy (WIDGET (jobs_dlg));
1370 }
1371 #endif
1372 
1373 /* --------------------------------------------------------------------------------------------- */

/* [previous][next][first][last][top][bottom][index][help]  */