Ticket #268 (Allow using SI-based size prefixes)
[free-mc.git] / src / boxes.c
blobc2707efa99dddb1871d7d0000051e412c8ead78e
1 /* Some misc dialog boxes for the program.
3 Copyright (C) 1994, 1995, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
4 2005, 2006, 2009 Free Software Foundation, Inc.
6 Authors: 1994, 1995 Miguel de Icaza
7 1995 Jakub Jelinek
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
23 /** \file boxes.c
24 * \brief Source: Some misc dialog boxes for the program
27 #include <config.h>
29 #include <ctype.h>
30 #include <signal.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
37 #include "global.h"
39 #include "../src/tty/tty.h"
40 #include "../src/tty/color.h" /* INPUT_COLOR */
41 #include "../src/tty/key.h" /* XCTRL and ALT macros */
43 #include "dialog.h" /* The nice dialog manager */
44 #include "widget.h" /* The widgets for the nice dialog manager */
45 #include "wtools.h"
46 #include "setup.h" /* For profile_name */
47 #include "../src/mcconfig/mcconfig.h" /* Load/save user formats */
48 #include "command.h" /* For cmdline */
49 #include "dir.h"
50 #include "panel.h"
51 #include "boxes.h"
52 #include "main.h" /* For the confirm_* variables */
53 #include "tree.h"
54 #include "layout.h" /* for get_nth_panel_name proto */
55 #include "background.h" /* task_list */
56 #include "strutil.h"
58 #ifdef HAVE_CHARSET
59 #include "charsets.h"
60 #include "selcodepage.h"
61 #endif
63 #ifdef USE_NETCODE
64 # include "../vfs/ftpfs.h"
65 #endif
67 #ifdef USE_VFS
68 #include "../vfs/gc.h"
69 #endif
71 static int DISPLAY_X = 45, DISPLAY_Y = 14;
73 static Dlg_head *dd;
74 static WRadio *my_radio;
75 static WInput *user;
76 static WInput *status;
77 static WCheck *check_status;
78 static int current_mode;
80 static char **displays_status;
82 /* Controls whether the array strings have been translated */
83 static const char *displays [LIST_TYPES] = {
84 N_("&Full file list"),
85 N_("&Brief file list"),
86 N_("&Long file list"),
87 N_("&User defined:")
90 /* Index in displays[] for "user defined" */
91 #define USER_TYPE 3
93 static int user_hotkey = 'u';
95 static cb_ret_t
96 display_callback (struct Dlg_head *h, dlg_msg_t msg, int parm)
98 switch (msg) {
99 case DLG_UNFOCUS:
100 if (dlg_widget_active (my_radio)) {
101 assign_text (status, displays_status[my_radio->sel]);
102 input_set_point (status, 0);
104 return MSG_HANDLED;
106 case DLG_KEY:
107 if (parm == '\n') {
108 if (dlg_widget_active (my_radio)) {
109 assign_text (status, displays_status[my_radio->sel]);
110 dlg_stop (h);
111 return MSG_HANDLED;
114 if (dlg_widget_active (user)) {
115 h->ret_value = B_USER + 6;
116 dlg_stop (h);
117 return MSG_HANDLED;
120 if (dlg_widget_active (status)) {
121 h->ret_value = B_USER + 7;
122 dlg_stop (h);
123 return MSG_HANDLED;
127 if (g_ascii_tolower (parm) == user_hotkey && dlg_widget_active (user)
128 && dlg_widget_active (status)) {
129 my_radio->sel = 3;
130 dlg_select_widget (my_radio); /* force redraw */
131 dlg_select_widget (user);
132 return MSG_HANDLED;
134 return MSG_NOT_HANDLED;
136 default:
137 return default_dlg_callback (h, msg, parm);
141 static void
142 display_init (int radio_sel, char *init_text, int _check_status,
143 char **_status)
145 static const char *display_title = N_("Listing mode");
146 static int i18n_displays_flag;
147 const char *user_mini_status = _("user &Mini status");
148 const char *ok_button = _("&OK");
149 const char *cancel_button = _("&Cancel");
151 static int button_start = 30;
153 displays_status = _status;
155 if (!i18n_displays_flag) {
156 int i, l, maxlen = 0;
157 const char *cp;
159 display_title = _(display_title);
160 for (i = 0; i < LIST_TYPES; i++) {
161 displays[i] = _(displays[i]);
162 if ((l = str_term_width1 (displays[i])) > maxlen)
163 maxlen = l;
166 i = str_term_width1 (ok_button) + 5;
167 l = str_term_width1 (cancel_button) + 3;
168 l = max (i, l);
170 i = maxlen + l + 16;
171 if (i > DISPLAY_X)
172 DISPLAY_X = i;
174 i = str_term_width1 (user_mini_status) + 13;
175 if (i > DISPLAY_X)
176 DISPLAY_X = i;
178 i = str_term_width1 (display_title) + 10;
179 if (i > DISPLAY_X)
180 DISPLAY_X = i;
182 button_start = DISPLAY_X - l - 5;
184 /* get hotkey of user-defined format string */
185 cp = strchr (displays[USER_TYPE], '&');
186 if (cp != NULL && *++cp != '\0')
187 user_hotkey = g_ascii_tolower ((gchar) cp[0]);
189 i18n_displays_flag = 1;
191 dd = create_dlg (0, 0, DISPLAY_Y, DISPLAY_X, dialog_colors,
192 display_callback, "[Listing Mode...]", display_title,
193 DLG_CENTER | DLG_REVERSE);
195 add_widget (dd,
196 button_new (4, button_start, B_CANCEL, NORMAL_BUTTON,
197 cancel_button, 0));
199 add_widget (dd,
200 button_new (3, button_start, B_ENTER, DEFPUSH_BUTTON,
201 ok_button, 0));
203 status =
204 input_new (10, 9, INPUT_COLOR, DISPLAY_X - 14, _status[radio_sel],
205 "mini-input", INPUT_COMPLETE_DEFAULT);
206 add_widget (dd, status);
207 input_set_point (status, 0);
209 check_status =
210 check_new (9, 5, _check_status, user_mini_status);
211 add_widget (dd, check_status);
213 user =
214 input_new (7, 9, INPUT_COLOR, DISPLAY_X - 14, init_text,
215 "user-fmt-input", INPUT_COMPLETE_DEFAULT);
216 add_widget (dd, user);
217 input_set_point (user, 0);
219 my_radio = radio_new (3, 5, LIST_TYPES, displays);
220 my_radio->sel = my_radio->pos = current_mode;
221 add_widget (dd, my_radio);
225 display_box (WPanel *panel, char **userp, char **minip, int *use_msformat, int num)
227 int result, i;
228 char *section = NULL;
229 const char *p;
231 if (!panel) {
232 p = get_nth_panel_name (num);
233 panel = g_new (WPanel, 1);
234 panel->list_type = list_full;
235 panel->user_format = g_strdup (DEFAULT_USER_FORMAT);
236 panel->user_mini_status = 0;
237 for (i = 0; i < LIST_TYPES; i++)
238 panel->user_status_format[i] = g_strdup (DEFAULT_USER_FORMAT);
239 section = g_strconcat ("Temporal:", p, (char *) NULL);
240 if (! mc_config_has_group (mc_main_config, section)) {
241 g_free (section);
242 section = g_strdup (p);
244 panel_load_setup (panel, section);
245 g_free (section);
248 current_mode = panel->list_type;
249 display_init (current_mode, panel->user_format,
250 panel->user_mini_status, panel->user_status_format);
252 run_dlg (dd);
254 result = -1;
256 if (section) {
257 g_free (panel->user_format);
258 for (i = 0; i < LIST_TYPES; i++)
259 g_free (panel->user_status_format [i]);
260 g_free (panel);
263 if (dd->ret_value != B_CANCEL){
264 result = my_radio->sel;
265 *userp = g_strdup (user->buffer);
266 *minip = g_strdup (status->buffer);
267 *use_msformat = check_status->state & C_BOOL;
269 destroy_dlg (dd);
271 return result;
274 static int SORT_X = 60, SORT_Y = 14;
276 static const char *sort_orders_names [SORT_TYPES];
278 sortfn *
279 sort_box (sortfn *sort_fn, int *reverse, int *case_sensitive, int *exec_first)
281 int i, r, l;
282 sortfn *result;
283 WCheck *c, *case_sense, *exec_ff;
285 const char *ok_button = _("&OK");
286 const char *cancel_button = _("&Cancel");
287 const char *reverse_label = _("&Reverse");
288 const char *case_label = _("case sensi&tive");
289 const char *sort_title = _("Sort order");
290 const char *exec_label = _("Executable first");
292 static int i18n_sort_flag = 0, check_pos = 0, button_pos = 0;
294 if (!i18n_sort_flag) {
295 int maxlen = 0;
296 for (i = SORT_TYPES - 1; i >= 0; i--) {
297 sort_orders_names[i] = _(sort_orders[i].sort_name);
298 r = str_term_width1 (sort_orders_names[i]);
299 if (r > maxlen)
300 maxlen = r;
303 check_pos = maxlen + 9;
305 r = str_term_width1 (reverse_label) + 4;
306 i = str_term_width1 (case_label) + 4;
307 if (i > r)
308 r = i;
310 l = str_term_width1 (ok_button) + 6;
311 i = str_term_width1 (cancel_button) + 4;
312 if (i > l)
313 l = i;
315 i = check_pos + max (r, l) + 2;
317 if (i > SORT_X)
318 SORT_X = i;
320 i = str_term_width1 (sort_title) + 6;
321 if (i > SORT_X)
322 SORT_X = i;
324 button_pos = SORT_X - l - 2;
326 i18n_sort_flag = 1;
329 result = 0;
331 for (i = 0; i < SORT_TYPES; i++)
332 if ((sortfn *) (sort_orders[i].sort_fn) == sort_fn) {
333 current_mode = i;
334 break;
337 dd = create_dlg (0, 0, SORT_Y, SORT_X, dialog_colors, NULL,
338 "[Sort Order...]", sort_title, DLG_CENTER | DLG_REVERSE);
340 add_widget (dd,
341 button_new (10, button_pos, B_CANCEL, NORMAL_BUTTON,
342 cancel_button, 0));
344 add_widget (dd,
345 button_new (9, button_pos, B_ENTER, DEFPUSH_BUTTON,
346 ok_button, 0));
348 exec_ff = check_new (5, check_pos, *exec_first, exec_label);
349 add_widget (dd, exec_ff);
350 case_sense = check_new (4, check_pos, *case_sensitive, case_label);
351 add_widget (dd, case_sense);
352 c = check_new (3, check_pos, *reverse, reverse_label);
353 add_widget (dd, c);
355 my_radio = radio_new (3, 3, SORT_TYPES, sort_orders_names);
356 my_radio->sel = my_radio->pos = current_mode;
358 add_widget (dd, my_radio);
359 run_dlg (dd);
361 r = dd->ret_value;
362 if (r != B_CANCEL) {
363 result = (sortfn *) sort_orders[my_radio->sel].sort_fn;
364 *reverse = c->state & C_BOOL;
365 *case_sensitive = case_sense->state & C_BOOL;
366 *exec_first = exec_ff->state & C_BOOL;
367 } else
368 result = sort_fn;
369 destroy_dlg (dd);
371 return result;
374 #define CONFY 11
375 #define CONFX 46
377 static int my_delete;
378 static int my_directory_hotlist_delete;
379 static int my_overwrite;
380 static int my_execute;
381 static int my_exit;
383 static QuickWidget conf_widgets [] = {
384 { quick_button, 4, 6, 4, CONFY, N_("&Cancel"),
385 0, B_CANCEL, 0, 0, NULL , NULL, NULL},
386 { quick_button, 4, 6, 3, CONFY, N_("&OK"),
387 0, B_ENTER, 0, 0, NULL , NULL, NULL},
389 { quick_checkbox, 1, 13, 7, CONFY, N_(" confirm di&Rectory hotlist delete "),
390 11, 0, &my_directory_hotlist_delete, NULL, NULL , NULL, NULL},
391 { quick_checkbox, 1, 13, 6, CONFY, N_(" confirm &Exit "),
392 9, 0, &my_exit, 0, NULL , NULL, NULL},
393 { quick_checkbox, 1, 13, 5, CONFY, N_(" confirm e&Xecute "),
394 10, 0, &my_execute, 0, NULL , NULL, NULL},
395 { quick_checkbox, 1, 13, 4, CONFY, N_(" confirm o&Verwrite "),
396 10, 0, &my_overwrite, 0, NULL , NULL, NULL},
397 { quick_checkbox, 1, 13, 3, CONFY, N_(" confirm &Delete "),
398 9, 0, &my_delete, 0, NULL , NULL, NULL},
399 NULL_QuickWidget
402 static QuickDialog confirmation =
403 { CONFX, CONFY, -1, -1, N_(" Confirmation "), "[Confirmation]",
404 conf_widgets, 0
407 void
408 confirm_box (void)
411 #ifdef ENABLE_NLS
412 static int i18n_flag = 0;
414 if (!i18n_flag)
416 register int i = sizeof(conf_widgets)/sizeof(QuickWidget) - 1;
417 int l1, maxlen = 0;
418 while (i--)
420 conf_widgets [i].text = _(conf_widgets [i].text);
421 l1 = str_term_width1 (conf_widgets [i].text) + 3;
422 if (l1 > maxlen)
423 maxlen = l1;
427 * If buttons start on 4/6, checkboxes (with some add'l space)
428 * must take not more than it.
430 confirmation.xlen = (maxlen + 5) * 6 / 4;
433 * And this for the case when buttons with some space to the right
434 * do not fit within 2/6
436 l1 = str_term_width1 (conf_widgets [0].text) + 3;
437 i = str_term_width1 (conf_widgets [1].text) + 5;
438 if (i > l1)
439 l1 = i;
441 i = (l1 + 3) * 6 / 2;
442 if (i > confirmation.xlen)
443 confirmation.xlen = i;
445 confirmation.title = _(confirmation.title);
447 i18n_flag = confirmation.i18n = 1;
450 #endif /* ENABLE_NLS */
452 my_delete = confirm_delete;
453 my_overwrite = confirm_overwrite;
454 my_execute = confirm_execute;
455 my_exit = confirm_exit;
456 my_directory_hotlist_delete = confirm_directory_hotlist_delete;
458 if (quick_dialog (&confirmation) != B_CANCEL){
459 confirm_delete = my_delete;
460 confirm_overwrite = my_overwrite;
461 confirm_execute = my_execute;
462 confirm_exit = my_exit;
463 confirm_directory_hotlist_delete = my_directory_hotlist_delete;
467 #define DISPY 12
468 #define DISPX 46
471 #ifndef HAVE_CHARSET
473 static int new_mode;
474 static int new_meta;
476 static const char *display_bits_str [] =
477 { N_("UTF-8 output"), N_("Full 8 bits output"), N_("ISO 8859-1"), N_("7 bits") };
479 static QuickWidget display_widgets [] = {
480 { quick_button, DISPX/2+7, DISPX, 7, DISPY, N_("&Cancel"),
481 0, B_CANCEL, 0, 0, NULL , NULL, NULL},
482 { quick_button, DISPX/2+7, DISPX, 8, DISPY, N_("&OK"),
483 0, B_ENTER, 0, 0, NULL , NULL, NULL},
484 { quick_checkbox, 4, DISPX, 8, DISPY, N_("F&ull 8 bits input"),
485 0, 0, &new_meta, 0, NULL , NULL, NULL},
486 { quick_radio, 4, DISPX, 3, DISPY, "", 4, 0,
487 &new_mode, const_cast(char **, display_bits_str), NULL , NULL, NULL},
488 NULL_QuickWidget
491 static QuickDialog display_bits =
492 { DISPX, DISPY, -1, -1, N_(" Display bits "), "[Display bits]",
493 display_widgets, 0 };
495 void
496 display_bits_box (void)
498 int current_mode;
500 #ifdef ENABLE_NLS
501 static int i18n_flag = 0;
502 if (!i18n_flag)
504 register int i;
505 int l1, maxlen = 0;
506 for (i = 0; i < 3; i++)
508 display_widgets [i].text = _(display_widgets[i].text);
509 display_bits_str [i] = _(display_bits_str [i]);
510 l1 = str_term_width1 (display_bits_str [i]);
511 if (l1 > maxlen)
512 maxlen = l1;
514 l1 = str_term_width1 (display_widgets [2].text);
515 if (l1 > maxlen)
516 maxlen = l1;
519 display_bits.xlen = (maxlen + 5) * 6 / 4;
521 /* See above confirm_box */
522 l1 = str_term_width1 (display_widgets [0].text) + 3;
523 i = str_term_width1 (display_widgets [1].text) + 5;
524 if (i > l1)
525 l1 = i;
527 i = (l1 + 3) * 6 / 2;
528 if (i > display_bits.xlen)
529 display_bits.xlen = i;
531 display_bits.title = _(display_bits.title);
532 i18n_flag = display_bits.i18n = 1;
535 #endif /* ENABLE_NLS */
537 if (full_eight_bits)
538 current_mode = 0;
539 else if (eight_bit_clean)
540 current_mode = 1;
541 else
542 current_mode = 2;
544 display_widgets [3].value = current_mode;
545 new_meta = !use_8th_bit_as_meta;
546 if (quick_dialog (&display_bits) != B_ENTER)
547 return;
549 eight_bit_clean = new_mode < 3;
550 full_eight_bits = new_mode < 2;
551 #ifdef HAVE_SLANG
552 tty_display_8bit (full_eight_bits != 0);
553 #else
554 tty_display_8bit (eight_bit_clean != 0);
555 #endif
556 use_8th_bit_as_meta = !new_meta;
560 #else /* HAVE_CHARSET */
563 static int new_display_codepage;
565 static WLabel *cplabel;
566 static WCheck *inpcheck;
568 static int
569 sel_charset_button (int action)
571 int new_dcp;
573 (void) action;
575 new_dcp = select_charset (0, 0, new_display_codepage, TRUE);
577 if (new_dcp != SELECT_CHARSET_CANCEL) {
578 const char *cpname;
579 char buf[BUF_TINY];
581 new_display_codepage = new_dcp;
582 cpname = (new_display_codepage == SELECT_CHARSET_OTHER_8BIT) ?
583 _("Other 8 bit") : codepages[new_display_codepage].name;
584 if (cpname != NULL)
585 utf8_display = str_isutf8 (cpname);
586 /* avoid strange bug with label repainting */
587 g_snprintf (buf, sizeof (buf), "%-27s", cpname);
588 label_set_text (cplabel, buf);
591 return 0;
594 static Dlg_head *
595 init_disp_bits_box (void)
597 const char *cpname;
598 Dlg_head *dbits_dlg;
600 do_refresh ();
602 dbits_dlg =
603 create_dlg (0, 0, DISPY, DISPX, dialog_colors, NULL,
604 "[Display bits]", _(" Display bits "), DLG_CENTER | DLG_REVERSE);
606 add_widget (dbits_dlg,
607 label_new (3, 4, _("Input / display codepage:")));
609 cpname = (new_display_codepage < 0)
610 ? _("Other 8 bit")
611 : codepages[new_display_codepage].name;
612 cplabel = label_new (4, 4, cpname);
613 add_widget (dbits_dlg, cplabel);
615 add_widget (dbits_dlg,
616 button_new (DISPY - 3, DISPX / 2 + 3, B_CANCEL,
617 NORMAL_BUTTON, _("&Cancel"), 0));
618 add_widget (dbits_dlg,
619 button_new (DISPY - 3, 7, B_ENTER, NORMAL_BUTTON, _("&OK"),
620 0));
622 inpcheck =
623 check_new (6, 4, !use_8th_bit_as_meta, _("F&ull 8 bits input"));
624 add_widget (dbits_dlg, inpcheck);
626 cpname = _("&Select");
627 add_widget (dbits_dlg,
628 button_new (4, DISPX - 8 - str_term_width1 (cpname), B_USER,
629 NORMAL_BUTTON, cpname, sel_charset_button));
631 return dbits_dlg;
634 void
635 display_bits_box (void)
637 Dlg_head *dbits_dlg;
638 new_display_codepage = display_codepage;
640 application_keypad_mode ();
641 dbits_dlg = init_disp_bits_box ();
643 run_dlg (dbits_dlg);
645 if (dbits_dlg->ret_value == B_ENTER) {
646 const char *errmsg;
647 display_codepage = new_display_codepage;
648 errmsg =
649 init_translation_table (source_codepage, display_codepage);
650 if (errmsg)
651 message (D_ERROR, MSG_ERROR, "%s", errmsg);
652 #ifdef HAVE_SLANG
653 tty_display_8bit (display_codepage != 0 && display_codepage != 1);
654 #else
655 tty_display_8bit (display_codepage != 0);
656 #endif
657 use_8th_bit_as_meta = !(inpcheck->state & C_BOOL);
659 destroy_dlg (dbits_dlg);
660 repaint_screen ();
663 #endif /* HAVE_CHARSET */
666 #define TREE_Y 20
667 #define TREE_X 60
669 static cb_ret_t
670 tree_callback (struct Dlg_head *h, dlg_msg_t msg, int parm)
672 switch (msg) {
674 case DLG_POST_KEY:
675 /* The enter key will be processed by the tree widget */
676 if (parm == '\n') {
677 h->ret_value = B_ENTER;
678 dlg_stop (h);
680 return MSG_HANDLED;
682 default:
683 return default_dlg_callback (h, msg, parm);
687 /* Show tree in a box, not on a panel */
688 char *
689 tree_box (const char *current_dir)
691 WTree *mytree;
692 Dlg_head *dlg;
693 char *val;
694 WButtonBar *bar;
696 (void) current_dir;
697 /* Create the components */
698 dlg = create_dlg (0, 0, TREE_Y, TREE_X, dialog_colors,
699 tree_callback, "[Directory Tree]", NULL, DLG_CENTER | DLG_REVERSE);
700 mytree = tree_new (0, 2, 2, TREE_Y - 6, TREE_X - 5);
701 add_widget (dlg, mytree);
702 bar = buttonbar_new(1);
703 add_widget (dlg, bar);
704 ((Widget *) bar)->x = 0;
705 ((Widget *) bar)->y = LINES - 1;
707 run_dlg (dlg);
708 if (dlg->ret_value == B_ENTER)
709 val = g_strdup (tree_selected_name (mytree));
710 else
711 val = 0;
713 destroy_dlg (dlg);
714 return val;
717 #ifdef USE_VFS
719 #if defined(USE_NETCODE)
720 #define VFSY 17
721 #define VFS_WIDGETBASE 10
722 #else
723 #define VFSY 8
724 #define VFS_WIDGETBASE 0
725 #endif
727 #define VFSX 56
729 static char *ret_timeout;
731 #if defined(USE_NETCODE)
732 static char *ret_passwd;
733 static char *ret_directory_timeout;
734 static char *ret_ftp_proxy;
735 static int ret_use_netrc;
736 static int ret_ftpfs_use_passive_connections;
737 static int ret_ftpfs_use_passive_connections_over_proxy;
738 #endif
740 static QuickWidget confvfs_widgets [] = {
741 { quick_button, 30, VFSX, VFSY - 3, VFSY, N_("&Cancel"),
742 0, B_CANCEL, 0, 0, NULL , NULL, NULL},
743 { quick_button, 12, VFSX, VFSY - 3, VFSY, N_("&OK"),
744 0, B_ENTER, 0, 0, NULL , NULL, NULL},
745 #if defined(USE_NETCODE)
746 { quick_checkbox, 4, VFSX, 12, VFSY, N_("Use passive mode over pro&xy"), 0, 0,
747 &ret_ftpfs_use_passive_connections_over_proxy, 0, NULL , NULL, NULL},
748 { quick_checkbox, 4, VFSX, 11, VFSY, N_("Use &passive mode"), 0, 0,
749 &ret_ftpfs_use_passive_connections, 0, NULL , NULL, NULL},
750 { quick_checkbox, 4, VFSX, 10, VFSY, N_("&Use ~/.netrc"), 0, 0,
751 &ret_use_netrc, 0, NULL , NULL, NULL},
752 { quick_input, 4, VFSX, 9, VFSY, "", 48, 0, 0, &ret_ftp_proxy,
753 "input-ftp-proxy" , NULL, NULL},
754 { quick_checkbox, 4, VFSX, 8, VFSY, N_("&Always use ftp proxy"), 0, 0,
755 &ftpfs_always_use_proxy, 0, NULL , NULL, NULL},
756 { quick_label, 49, VFSX, 7, VFSY, N_("sec"),
757 0, 0, 0, 0, NULL , NULL, NULL},
758 { quick_input, 38, VFSX, 7, VFSY, "", 10, 0, 0, &ret_directory_timeout,
759 "input-timeout" , NULL, NULL},
760 { quick_label, 4, VFSX, 7, VFSY, N_("ftpfs directory cache timeout:"),
761 0, 0, 0, 0, NULL , NULL, NULL},
762 { quick_input, 4, VFSX, 6, VFSY, "", 48, 0, 0, &ret_passwd,
763 "input-passwd" , NULL, NULL},
764 { quick_label, 4, VFSX, 5, VFSY, N_("ftp anonymous password:"),
765 0, 0, 0, 0, NULL , NULL, NULL},
766 #endif
767 { quick_label, 49, VFSX, 3, VFSY, "sec",
768 0, 0, 0, 0, NULL , NULL, NULL},
769 { quick_input, 38, VFSX, 3, VFSY, "", 10, 0, 0, &ret_timeout,
770 "input-timo-vfs" , NULL, NULL},
771 { quick_label, 4, VFSX, 3, VFSY, N_("Timeout for freeing VFSs:"),
772 0, 0, 0, 0, NULL , NULL, NULL},
773 NULL_QuickWidget
776 static QuickDialog confvfs_dlg =
777 { VFSX, VFSY, -1, -1, N_(" Virtual File System Setting "),
778 "[Virtual FS]", confvfs_widgets, 0 };
780 void
781 configure_vfs (void)
783 char buffer2[BUF_TINY];
784 #if defined(USE_NETCODE)
785 char buffer3[BUF_TINY];
787 ret_use_netrc = use_netrc;
788 ret_ftpfs_use_passive_connections = ftpfs_use_passive_connections;
789 ret_ftpfs_use_passive_connections_over_proxy = ftpfs_use_passive_connections_over_proxy;
790 g_snprintf(buffer3, sizeof (buffer3), "%i", ftpfs_directory_timeout);
791 confvfs_widgets[8].text = buffer3;
792 confvfs_widgets[10].text = ftpfs_anonymous_passwd;
793 confvfs_widgets[5].text = ftpfs_proxy_host;
794 #endif
795 g_snprintf (buffer2, sizeof (buffer2), "%i", vfs_timeout);
796 confvfs_widgets [3 + VFS_WIDGETBASE].text = buffer2;
798 if (quick_dialog (&confvfs_dlg) != B_CANCEL) {
799 vfs_timeout = atoi (ret_timeout);
800 g_free (ret_timeout);
801 if (vfs_timeout < 0 || vfs_timeout > 10000)
802 vfs_timeout = 10;
803 #if defined(USE_NETCODE)
804 g_free (ftpfs_anonymous_passwd);
805 ftpfs_anonymous_passwd = ret_passwd;
806 g_free (ftpfs_proxy_host);
807 ftpfs_proxy_host = ret_ftp_proxy;
808 ftpfs_directory_timeout = atoi(ret_directory_timeout);
809 use_netrc = ret_use_netrc;
810 ftpfs_use_passive_connections = ret_ftpfs_use_passive_connections;
811 ftpfs_use_passive_connections_over_proxy = ret_ftpfs_use_passive_connections_over_proxy;
812 g_free (ret_directory_timeout);
813 #endif
817 #endif /* USE_VFS */
819 char *
820 cd_dialog (void)
822 QuickDialog Quick_input;
823 QuickWidget quick_widgets [] = {
824 { quick_input, 6, 57, 2, 0, "", 50, 0, 0, 0, "input" , NULL, NULL},
825 { quick_label, 3, 57, 2, 0, "", 0, 0, 0, 0, NULL , NULL, NULL},
826 NULL_QuickWidget
828 char *my_str;
829 int len;
831 Quick_input.xlen = 57;
832 Quick_input.title = _("Quick cd");
833 Quick_input.help = "[Quick cd]";
834 quick_widgets [0].value = 2; /* want cd like completion */
835 quick_widgets [1].text = _("cd");
836 quick_widgets [1].y_divisions =
837 quick_widgets [0].y_divisions = Quick_input.ylen = 5;
839 len = str_term_width1 (quick_widgets [1].text);
841 quick_widgets [0].relative_x =
842 quick_widgets [1].relative_x + len + 1;
844 Quick_input.xlen = len + quick_widgets [0].hotkey_pos + 7;
845 quick_widgets [0].x_divisions =
846 quick_widgets [1].x_divisions = Quick_input.xlen;
848 Quick_input.i18n = 1;
849 Quick_input.xpos = 2;
850 Quick_input.ypos = LINES - 2 - Quick_input.ylen;
851 quick_widgets [0].str_result = &my_str;
853 Quick_input.widgets = quick_widgets;
854 if (quick_dialog (&Quick_input) != B_CANCEL){
855 return my_str;
856 } else
857 return 0;
860 void
861 symlink_dialog (const char *existing, const char *new, char **ret_existing,
862 char **ret_new)
864 QuickDialog Quick_input;
865 QuickWidget quick_widgets[] = {
866 {quick_button, 50, 80, 6, 8, N_("&Cancel"), 0, B_CANCEL, 0, 0,
867 NULL, NULL, NULL},
868 {quick_button, 16, 80, 6, 8, N_("&OK"), 0, B_ENTER, 0, 0, NULL, NULL, NULL},
869 {quick_input, 4, 80, 5, 8, "", 58, 0, 0, 0, "input-1", NULL, NULL},
870 {quick_label, 4, 80, 4, 8, N_("Symbolic link filename:"), 0, 0, 0,
871 0, NULL, NULL, NULL},
872 {quick_input, 4, 80, 3, 8, "", 58, 0, 0, 0, "input-2", NULL, NULL},
873 {quick_label, 4, 80, 2, 8,
874 N_("Existing filename (filename symlink will point to):"), 0, 0,
875 0, 0, NULL, NULL, NULL},
876 NULL_QuickWidget
879 Quick_input.xlen = 64;
880 Quick_input.ylen = 12;
881 Quick_input.title = N_("Symbolic link");
882 Quick_input.help = "[File Menu]";
883 Quick_input.i18n = 0;
884 quick_widgets[2].text = new;
885 quick_widgets[4].text = existing;
886 Quick_input.xpos = -1;
887 quick_widgets[2].str_result = ret_new;
888 quick_widgets[4].str_result = ret_existing;
890 Quick_input.widgets = quick_widgets;
891 if (quick_dialog (&Quick_input) == B_CANCEL) {
892 *ret_new = NULL;
893 *ret_existing = NULL;
897 #ifdef WITH_BACKGROUND
898 #define B_STOP (B_USER+1)
899 #define B_RESUME (B_USER+2)
900 #define B_KILL (B_USER+3)
902 static int JOBS_X = 60;
903 #define JOBS_Y 15
904 static WListbox *bg_list;
905 static Dlg_head *jobs_dlg;
907 static void
908 jobs_fill_listbox (void)
910 static const char *state_str [2];
911 TaskList *tl = task_list;
913 if (!state_str [0]){
914 state_str [0] = _("Running ");
915 state_str [1] = _("Stopped");
918 while (tl){
919 char *s;
921 s = g_strconcat (state_str [tl->state], " ", tl->info, (char *) NULL);
922 listbox_add_item (bg_list, LISTBOX_APPEND_AT_END, 0, s, (void *) tl);
923 g_free (s);
924 tl = tl->next;
928 static int
929 task_cb (int action)
931 TaskList *tl;
932 int sig = 0;
934 if (!bg_list->list)
935 return 0;
937 /* Get this instance information */
938 tl = (TaskList *) bg_list->current->data;
940 # ifdef SIGTSTP
941 if (action == B_STOP){
942 sig = SIGSTOP;
943 tl->state = Task_Stopped;
944 } else if (action == B_RESUME){
945 sig = SIGCONT;
946 tl->state = Task_Running;
947 } else
948 # endif
949 if (action == B_KILL){
950 sig = SIGKILL;
953 if (sig == SIGINT)
954 unregister_task_running (tl->pid, tl->fd);
956 kill (tl->pid, sig);
957 listbox_remove_list (bg_list);
958 jobs_fill_listbox ();
960 /* This can be optimized to just redraw this widget :-) */
961 dlg_redraw (jobs_dlg);
963 return 0;
966 static struct
968 const char* name;
969 int xpos;
970 int value;
971 int (*callback)(int);
973 job_buttons [] =
975 {N_("&Stop"), 3, B_STOP, task_cb},
976 {N_("&Resume"), 12, B_RESUME, task_cb},
977 {N_("&Kill"), 23, B_KILL, task_cb},
978 {N_("&OK"), 35, B_CANCEL, NULL }
981 void
982 jobs_cmd (void)
984 register int i;
985 int n_buttons = sizeof (job_buttons) / sizeof (job_buttons[0]);
987 #ifdef ENABLE_NLS
988 static int i18n_flag = 0;
989 if (!i18n_flag)
991 int startx = job_buttons [0].xpos;
992 int len;
994 for (i = 0; i < n_buttons; i++)
996 job_buttons [i].name = _(job_buttons [i].name);
998 len = str_term_width1 (job_buttons [i].name) + 4;
999 JOBS_X = max (JOBS_X, startx + len + 3);
1001 job_buttons [i].xpos = startx;
1002 startx += len;
1005 /* Last button - Ok a.k.a. Cancel :) */
1006 job_buttons [n_buttons - 1].xpos =
1007 JOBS_X - str_term_width1 (job_buttons [n_buttons - 1].name) - 7;
1009 i18n_flag = 1;
1011 #endif /* ENABLE_NLS */
1013 jobs_dlg = create_dlg (0, 0, JOBS_Y, JOBS_X, dialog_colors, NULL,
1014 "[Background jobs]", _("Background Jobs"),
1015 DLG_CENTER | DLG_REVERSE);
1017 bg_list = listbox_new (2, 3, JOBS_Y - 9, JOBS_X - 7, NULL);
1018 add_widget (jobs_dlg, bg_list);
1020 i = n_buttons;
1021 while (i--)
1023 add_widget (jobs_dlg, button_new (JOBS_Y-4,
1024 job_buttons [i].xpos, job_buttons [i].value,
1025 NORMAL_BUTTON, job_buttons [i].name,
1026 job_buttons [i].callback));
1029 /* Insert all of task information in the list */
1030 jobs_fill_listbox ();
1031 run_dlg (jobs_dlg);
1033 destroy_dlg (jobs_dlg);
1035 #endif /* WITH_BACKGROUND */
1037 #ifdef WITH_SMBFS
1038 struct smb_authinfo *
1039 vfs_smb_get_authinfo (const char *host, const char *share, const char *domain,
1040 const char *user)
1042 static int dialog_x = 44;
1043 enum { b0 = 3, dialog_y = 12};
1044 struct smb_authinfo *return_value;
1045 static const char* labs[] = {N_("Domain:"), N_("Username:"), N_("Password:")};
1046 static const char* buts[] = {N_("&OK"), N_("&Cancel")};
1047 static int ilen = 30, istart = 14;
1048 static int b2 = 30;
1049 char *title;
1050 WInput *in_password;
1051 WInput *in_user;
1052 WInput *in_domain;
1053 Dlg_head *auth_dlg;
1055 #ifdef ENABLE_NLS
1056 static int i18n_flag = 0;
1058 if (!i18n_flag)
1060 register int i = sizeof(labs)/sizeof(labs[0]);
1061 int l1, maxlen = 0;
1063 while (i--)
1065 l1 = str_term_width1 (labs [i] = _(labs [i]));
1066 if (l1 > maxlen)
1067 maxlen = l1;
1069 i = maxlen + ilen + 7;
1070 if (i > dialog_x)
1071 dialog_x = i;
1073 for (i = sizeof(buts)/sizeof(buts[0]), l1 = 0; i--; )
1075 l1 += str_term_width1 (buts [i] = _(buts [i]));
1077 l1 += 15;
1078 if (l1 > dialog_x)
1079 dialog_x = l1;
1081 ilen = dialog_x - 7 - maxlen; /* for the case of very long buttons :) */
1082 istart = dialog_x - 3 - ilen;
1084 b2 = dialog_x - (str_term_width1 (buts[1]) + 6);
1086 i18n_flag = 1;
1089 #endif /* ENABLE_NLS */
1091 if (!domain)
1092 domain = "";
1093 if (!user)
1094 user = "";
1096 title = g_strdup_printf (_("Password for \\\\%s\\%s"), host, share);
1098 auth_dlg = create_dlg (0, 0, dialog_y, dialog_x, dialog_colors, NULL,
1099 "[Smb Authinfo]", title, DLG_CENTER | DLG_REVERSE);
1101 g_free (title);
1103 in_user = input_new (5, istart, INPUT_COLOR, ilen, user, "auth_name", INPUT_COMPLETE_DEFAULT);
1104 add_widget (auth_dlg, in_user);
1106 in_domain = input_new (3, istart, INPUT_COLOR, ilen, domain, "auth_domain", INPUT_COMPLETE_DEFAULT);
1107 add_widget (auth_dlg, in_domain);
1108 add_widget (auth_dlg, button_new (9, b2, B_CANCEL, NORMAL_BUTTON,
1109 buts[1], 0));
1110 add_widget (auth_dlg, button_new (9, b0, B_ENTER, DEFPUSH_BUTTON,
1111 buts[0], 0));
1113 in_password = input_new (7, istart, INPUT_COLOR, ilen, "", "auth_password", INPUT_COMPLETE_DEFAULT);
1114 in_password->completion_flags = 0;
1115 in_password->is_password = 1;
1116 add_widget (auth_dlg, in_password);
1118 add_widget (auth_dlg, label_new (7, 3, labs[2]));
1119 add_widget (auth_dlg, label_new (5, 3, labs[1]));
1120 add_widget (auth_dlg, label_new (3, 3, labs[0]));
1122 run_dlg (auth_dlg);
1124 switch (auth_dlg->ret_value) {
1125 case B_CANCEL:
1126 return_value = 0;
1127 break;
1128 default:
1129 return_value = g_new (struct smb_authinfo, 1);
1130 if (return_value) {
1131 return_value->host = g_strdup (host);
1132 return_value->share = g_strdup (share);
1133 return_value->domain = g_strdup (in_domain->buffer);
1134 return_value->user = g_strdup (in_user->buffer);
1135 return_value->password = g_strdup (in_password->buffer);
1139 destroy_dlg (auth_dlg);
1141 return return_value;
1143 #endif /* WITH_SMBFS */