Merge branch '2123_crash_while_copy'
[midnight-commander.git] / src / boxes.c
blob8c6670435c39a2001603df767e5f382ff3369dfc
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 "lib/global.h"
39 #include "lib/tty/tty.h"
40 #include "lib/skin.h" /* INPUT_COLOR */
41 #include "lib/tty/key.h" /* XCTRL and ALT macros */
42 #include "lib/mcconfig.h" /* Load/save user formats */
43 #include "lib/strutil.h"
45 #ifdef ENABLE_VFS
46 #include "lib/vfs/mc-vfs/vfs.h" /* vfs_timeout */
47 #include "lib/vfs/mc-vfs/vfs-impl.h"
48 #endif
50 #ifdef USE_NETCODE
51 # include "lib/vfs/mc-vfs/ftpfs.h"
52 #endif
54 #include "dialog.h" /* The nice dialog manager */
55 #include "widget.h" /* The widgets for the nice dialog manager */
56 #include "wtools.h"
57 #include "setup.h" /* For profile_name */
58 #include "command.h" /* For cmdline */
59 #include "dir.h"
60 #include "panel.h" /* LIST_TYPES */
61 #include "boxes.h"
62 #include "main.h" /* For the confirm_* variables */
63 #include "tree.h"
64 #include "layout.h" /* for get_nth_panel_name proto */
65 #include "background.h" /* task_list */
67 #ifdef HAVE_CHARSET
68 #include "charsets.h"
69 #include "selcodepage.h"
70 #endif
73 static WRadio *display_radio;
74 static WInput *display_user_format;
75 static WInput *display_mini_status;
76 static WCheck *display_check_status;
77 static char **displays_status;
78 static int display_user_hotkey = 'u';
80 static cb_ret_t
81 display_callback (Dlg_head * h, Widget * sender, dlg_msg_t msg, int parm, void *data)
83 switch (msg)
85 case DLG_UNFOCUS:
86 if (dlg_widget_active (display_radio))
88 assign_text (display_mini_status, displays_status[display_radio->sel]);
89 input_set_point (display_mini_status, 0);
91 return MSG_HANDLED;
93 case DLG_KEY:
94 if (parm == '\n')
96 if (dlg_widget_active (display_radio))
98 assign_text (display_mini_status, displays_status[display_radio->sel]);
99 dlg_stop (h);
100 return MSG_HANDLED;
103 if (dlg_widget_active (display_user_format))
105 h->ret_value = B_USER + 6;
106 dlg_stop (h);
107 return MSG_HANDLED;
110 if (dlg_widget_active (display_mini_status))
112 h->ret_value = B_USER + 7;
113 dlg_stop (h);
114 return MSG_HANDLED;
118 if (g_ascii_tolower (parm) == display_user_hotkey && dlg_widget_active (display_user_format)
119 && dlg_widget_active (display_mini_status))
121 display_radio->sel = 3;
122 dlg_select_widget (display_radio); /* force redraw */
123 dlg_select_widget (display_user_format);
124 return MSG_HANDLED;
126 return MSG_NOT_HANDLED;
128 default:
129 return default_dlg_callback (h, sender, msg, parm, data);
133 static Dlg_head *
134 display_init (int radio_sel, char *init_text, int _check_status, char **_status)
136 int dlg_width = 48, dlg_height = 15;
137 Dlg_head *dd;
139 const int input_colors[3] =
141 INPUT_COLOR,
142 INPUT_UNCHANGED_COLOR,
143 INPUT_MARK_COLOR
146 /* Controls whether the array strings have been translated */
147 const char *displays[LIST_TYPES] = {
148 N_("&Full file list"),
149 N_("&Brief file list"),
150 N_("&Long file list"),
151 N_("&User defined:")
154 /* Index in displays[] for "user defined" */
155 const int user_type_idx = 3;
157 const char *display_title = N_("Listing mode");
158 const char *user_mini_status = N_("User &mini status");
159 const char *ok_name = N_("&OK");
160 const char *cancel_name = N_("&Cancel");
162 WButton *ok_button, *cancel_button;
165 int i, maxlen = 0;
166 const char *cp;
167 int ok_len, cancel_len;
169 #ifdef ENABLE_NLS
170 display_title = _(display_title);
171 user_mini_status = _(user_mini_status);
172 ok_name = _(ok_name);
173 cancel_name = _(cancel_name);
175 for (i = 0; i < LIST_TYPES; i++)
176 displays[i] = _(displays[i]);
177 #endif
179 /* get hotkey of user-defined format string */
180 cp = strchr (displays[user_type_idx], '&');
181 if (cp != NULL && *++cp != '\0')
182 display_user_hotkey = g_ascii_tolower (*cp);
184 /* xpos will be fixed later */
185 ok_button = button_new (dlg_height - 3, 0, B_ENTER, DEFPUSH_BUTTON, ok_name, 0);
186 ok_len = button_get_len (ok_button);
187 cancel_button = button_new (dlg_height - 3, 0, B_CANCEL, NORMAL_BUTTON, cancel_name, 0);
188 cancel_len = button_get_len (cancel_button);
190 dlg_width = max (dlg_width, str_term_width1 (display_title) + 10);
191 /* calculate max width of radiobutons */
192 for (i = 0; i < LIST_TYPES; i++)
193 maxlen = max (maxlen, str_term_width1 (displays[i]));
194 dlg_width = max (dlg_width, maxlen);
195 dlg_width = max (dlg_width, str_term_width1 (user_mini_status) + 13);
197 /* buttons */
198 dlg_width = max (dlg_width, ok_len + cancel_len + 8);
199 ok_button->widget.x = dlg_width / 3 - ok_len / 2;
200 cancel_button->widget.x = dlg_width * 2 / 3 - cancel_len / 2;
203 displays_status = _status;
205 dd = create_dlg (TRUE, 0, 0, dlg_height, dlg_width, dialog_colors,
206 display_callback, "[Listing Mode...]", display_title,
207 DLG_CENTER | DLG_REVERSE);
209 add_widget (dd, cancel_button);
210 add_widget (dd, ok_button);
212 display_mini_status = input_new (10, 8, (int *) input_colors, dlg_width - 12, _status[radio_sel],
213 "mini-input", INPUT_COMPLETE_DEFAULT);
214 add_widget (dd, display_mini_status);
215 input_set_point (display_mini_status, 0);
217 display_check_status = check_new (9, 4, _check_status, user_mini_status);
218 add_widget (dd, display_check_status);
220 display_user_format = input_new (7, 8, (int *) input_colors, dlg_width - 12, init_text,
221 "user-fmt-input", INPUT_COMPLETE_DEFAULT);
222 add_widget (dd, display_user_format);
223 input_set_point (display_user_format, 0);
225 display_radio = radio_new (3, 4, LIST_TYPES, displays);
226 display_radio->sel = display_radio->pos = radio_sel;
227 add_widget (dd, display_radio);
229 return dd;
232 /* return list type */
234 display_box (WPanel * panel, char **userp, char **minip, int *use_msformat, int num)
236 int result = -1;
237 Dlg_head *dd;
238 char *section = NULL;
239 size_t i;
241 if (panel == NULL)
243 const char *p = get_nth_panel_name (num);
244 panel = g_new (WPanel, 1);
245 panel->list_type = list_full;
246 panel->user_format = g_strdup (DEFAULT_USER_FORMAT);
247 panel->user_mini_status = 0;
248 for (i = 0; i < LIST_TYPES; i++)
249 panel->user_status_format[i] = g_strdup (DEFAULT_USER_FORMAT);
250 section = g_strconcat ("Temporal:", p, (char *) NULL);
251 if (!mc_config_has_group (mc_main_config, section))
253 g_free (section);
254 section = g_strdup (p);
256 panel_load_setup (panel, section);
257 g_free (section);
260 dd = display_init (panel->list_type, panel->user_format,
261 panel->user_mini_status, panel->user_status_format);
263 if (run_dlg (dd) != B_CANCEL)
265 result = display_radio->sel;
266 *userp = g_strdup (display_user_format->buffer);
267 *minip = g_strdup (display_mini_status->buffer);
268 *use_msformat = display_check_status->state & C_BOOL;
271 if (section != NULL)
273 g_free (panel->user_format);
274 for (i = 0; i < LIST_TYPES; i++)
275 g_free (panel->user_status_format[i]);
276 g_free (panel);
279 destroy_dlg (dd);
281 return result;
284 const panel_field_t *
285 sort_box (const panel_field_t * sort_format, int *reverse, int *case_sensitive, int *exec_first)
287 int dlg_width = 40, dlg_height = 7;
289 const char **sort_orders_names;
290 gsize sort_names_num;
292 int sort_idx = 0;
294 const panel_field_t *result = sort_format;
296 sort_orders_names = panel_get_sortable_fields (&sort_names_num);
297 dlg_height += sort_names_num;
300 int max_radio = 0, max_check = 0;
301 int ok_len, cancel_len;
302 gsize i;
304 QuickWidget quick_widgets[] = {
305 /* 0 */
306 QUICK_BUTTON (0, dlg_width, dlg_height - 3, dlg_height, N_("&Cancel"), B_CANCEL, NULL),
307 /* 1 */
308 QUICK_BUTTON (0, dlg_width, dlg_height - 3, dlg_height, N_("&OK"), B_ENTER, NULL),
309 /* 2 */
310 QUICK_CHECKBOX (0, dlg_width, 5, dlg_height, N_("&Reverse"), reverse),
311 /* 3 */
312 QUICK_CHECKBOX (0, dlg_width, 4, dlg_height, N_("Case sensi&tive"), case_sensitive),
313 /* 4 */
314 QUICK_CHECKBOX (0, dlg_width, 3, dlg_height, N_("Executable &first"), exec_first),
315 /* 5 */
316 QUICK_RADIO (4, dlg_width, 3, dlg_height, 0,
317 NULL, &sort_idx),
318 QUICK_END
321 QuickDialog quick_dlg = {
322 dlg_width, dlg_height, -1, -1,
323 N_("Sort order"), "[Sort Order...]",
324 quick_widgets, TRUE
327 quick_widgets[5].u.radio.items = sort_orders_names;
328 quick_widgets[5].u.radio.count = sort_names_num;
330 for (i = 0; i < sort_names_num; i++)
331 if (strcmp (sort_orders_names[i], _(sort_format->title_hotkey)) == 0)
333 sort_idx = i;
334 break;
337 #ifdef ENABLE_NLS
338 quick_dlg.title = _(quick_dlg.title);
339 /* buttons */
340 for (i = 0; i < 2; i++)
341 quick_widgets[i].u.button.text = _(quick_widgets[i].u.button.text);
342 /* checkboxes */
343 for (i = 2; i < 5; i++)
344 quick_widgets[i].u.checkbox.text = _(quick_widgets[i].u.checkbox.text);
345 #endif /* ENABLE_NlS */
347 /* buttons */
348 cancel_len = str_term_width1 (quick_widgets[0].u.button.text) + 4;
349 ok_len = str_term_width1 (quick_widgets[1].u.button.text) + 6;
350 /* checkboxes */
351 for (i = 2; i < 5; i++)
352 max_check = max (max_check, str_term_width1 (quick_widgets[i].u.checkbox.text) + 4);
353 /* radiobuttons */
354 for (i = 0; i < sort_names_num; i++)
355 max_radio = max (max_radio, str_term_width1 (sort_orders_names[i]) + 4);
357 /* dialog width */
358 dlg_width = max (dlg_width, str_term_width1 (quick_dlg.title) + 8);
359 dlg_width = max (dlg_width, ok_len + cancel_len + 8);
360 dlg_width = max (dlg_width, 2 * max (max_radio, max_check) + 8);
362 /* fix widget and dialog parameters */
363 /* dialog */
364 quick_dlg.xlen = dlg_width;
365 /* widgets */
366 for (i = 0; (size_t) i < sizeof (quick_widgets) / sizeof (quick_widgets[0]) - 1; i++)
367 quick_widgets[i].x_divisions = dlg_width;
368 /* buttons */
369 quick_widgets[0].relative_x = dlg_width * 2 / 3 - cancel_len / 2;
370 quick_widgets[1].relative_x = dlg_width / 3 - ok_len / 2;
371 /* checkboxes */
372 for (i = 2; i < 5; i++)
373 quick_widgets[i].relative_x = dlg_width / 2 + 2;
375 if (quick_dialog (&quick_dlg) != B_CANCEL)
376 result = panel_get_field_by_title_hotkey (sort_orders_names[sort_idx]);
378 if (result == NULL)
379 result = sort_format;
381 g_strfreev ((gchar **) sort_orders_names);
382 return result;
386 void
387 confirm_box (void)
389 const char *title = _("Confirmation");
391 QuickWidget conf_widgets[] = {
392 /* 0 */ QUICK_BUTTON (29, 46, 10, 13, N_("&Cancel"), B_CANCEL, NULL),
393 /* 1 */ QUICK_BUTTON (12, 46, 10, 13, N_("&OK"), B_ENTER, NULL),
394 /* TRANSLATORS: no need to translate 'Confirmation', it's just a context prefix */
395 /* 2 */ QUICK_CHECKBOX (3, 46, 8, 13, N_("Confirmation|&History cleanup"),
396 &confirm_history_cleanup),
397 /* 3 */ QUICK_CHECKBOX (3, 46, 7, 13, N_("Confirmation|&Directory hotlist delete"),
398 &confirm_directory_hotlist_delete),
399 /* 4 */ QUICK_CHECKBOX (3, 46, 6, 13, N_("Confirmation|E&xit"), &confirm_exit),
400 /* 5 */ QUICK_CHECKBOX (3, 46, 5, 13, N_("Confirmation|&Execute"), &confirm_execute),
401 /* 6 */ QUICK_CHECKBOX (3, 46, 4, 13, N_("Confirmation|O&verwrite"), &confirm_overwrite),
402 /* 7 */ QUICK_CHECKBOX (3, 46, 3, 13, N_("Confirmation|&Delete"), &confirm_delete),
403 QUICK_END
406 const size_t w_num = sizeof (conf_widgets) / sizeof (conf_widgets[0]) - 1;
408 /* dialog sizes */
409 int dlg_width = 46;
410 int dlg_height = w_num + 5;
412 size_t i;
413 int maxlen = 0;
414 int cancel_len, ok_len, blen;
416 #ifdef ENABLE_NLS
417 title = _(title);
419 for (i = 0; i < 2; i++)
420 conf_widgets[i].u.button.text = _(conf_widgets[i].u.button.text);
422 for (i = 2; i < w_num; i++)
423 conf_widgets[i].u.checkbox.text = Q_ (conf_widgets[i].u.checkbox.text);
424 #endif /* ENABLE_NLS */
426 /* maximumr length of checkboxes */
427 for (i = 2; i < w_num; i++)
428 maxlen = max (maxlen, str_term_width1 (conf_widgets[i].u.checkbox.text) + 4);
430 /* length of buttons */
431 cancel_len = str_term_width1 (conf_widgets[0].u.button.text) + 3;
432 ok_len = str_term_width1 (conf_widgets[1].u.button.text) + 5; /* default button */
434 blen = cancel_len + ok_len + 2;
436 dlg_width = max (maxlen, blen) + 6;
437 dlg_width = max (dlg_width, str_term_width1 (title) + 4);
439 /* correct widget parameters */
440 for (i = 0; i < w_num; i++)
442 conf_widgets[i].x_divisions = dlg_width;
443 conf_widgets[i].y_divisions = dlg_height;
446 conf_widgets[1].relative_x = dlg_width / 2 - blen / 2;
447 conf_widgets[0].relative_x = conf_widgets[1].relative_x + ok_len + 2;
450 QuickDialog confirmation = {
451 dlg_width, dlg_height, -1, -1, title,
452 "[Confirmation]", conf_widgets, 1
455 (void) quick_dialog (&confirmation);
460 #ifndef HAVE_CHARSET
461 void
462 display_bits_box (void) /* AB:FIXME: test dialog */
464 /* dialog sizes */
465 const int DISPY = 13;
466 const int DISPX = 46;
468 int new_meta = 0;
469 int current_mode;
471 const char *display_bits_str[] = {
472 N_("UTF-8 output"),
473 N_("Full 8 bits output"),
474 N_("ISO 8859-1"),
475 N_("7 bits")
478 QuickWidget display_widgets[] = {
479 /* 0 */ QUICK_BUTTON (15, DISPX, DISPY - 3, DISPY, N_("&Cancel"), B_CANCEL, NULL),
480 /* 1 */ QUICK_BUTTON (29, DISPX, DISPY - 3, DISPY, N_("&OK"), B_ENTER, NULL),
481 /* 2 */ QUICK_CHECKBOX (3, DISPX, 8, DISPY, N_("F&ull 8 bits input"), &new_meta),
482 /* 3 */ QUICK_RADIO (3, DISPX, 3, DISPY, 4, display_bits_str, &current_mode),
483 QUICK_END
486 QuickDialog display_bits = {
487 DISPX, DISPY, -1, -1, _("Display bits"),
488 "[Display bits]", display_widgets, TRUE
491 int i;
492 int l1, maxlen = 0;
493 int ok_len, cancel_len;
495 #ifdef ENABLE_NLS
496 static gboolean i18n_flag = FALSE;
498 if (!i18n_flag)
500 for (i = 0; i < 3; i++)
502 display_bits_str[i] = _(display_bits_str[i]);
505 display_widgets[0].u.button.text = _(display_widgets[0].u.button.text);
506 display_widgets[1].u.button.text = _(display_widgets[1].u.button.text);
507 display_widgets[2].u.checkbox.text = _(display_widgets[2].u.checkbox.text);
509 i18n_flag = TRUE;
511 #endif /* ENABLE_NLS */
513 /* radiobuttons */
514 for (i = 0; i < 3; i++)
515 maxlen = max (maxlen, str_term_width1 (display_bits_str[i]));
517 /* buttons */
518 cancel_len = str_term_width1 (display_widgets[0].u.button.text) + 2;
519 ok_len = str_term_width1 (display_widgets[1].u.button.text) + 4; /* default button */
521 l1 = max (cancel_len, ok_len);
523 display_bits.xlen = max (maxlen, l1) + 20;
525 for (i = 0; i < 4; i++)
526 display_widgets[i].x_divisions = display_bits.xlen;
528 display_widgets[0].relative_x = display_bits.xlen * 2 / 3 - cancel_len / 2;
529 display_widgets[1].relative_x = display_bits.xlen / 3 - ok_len / 2;
531 if (full_eight_bits)
532 current_mode = 0;
533 else if (eight_bit_clean)
534 current_mode = 1;
535 else
536 current_mode = 2;
538 new_meta = !use_8th_bit_as_meta;
540 if (quick_dialog (&display_bits) != B_CANCEL)
542 eight_bit_clean = current_mode < 3;
543 full_eight_bits = current_mode < 2;
544 #ifndef HAVE_SLANG
545 meta (stdscr, eight_bit_clean);
546 #else
547 SLsmg_Display_Eight_Bit = full_eight_bits ? 128 : 160;
548 #endif
549 use_8th_bit_as_meta = !new_meta;
553 #else /* HAVE_CHARSET */
555 static int new_display_codepage;
557 static WLabel *cplabel;
558 static WCheck *inpcheck;
560 static int
561 sel_charset_button (int action)
563 int new_dcp;
565 (void) action;
567 new_dcp = select_charset (-1, -1, new_display_codepage, TRUE);
569 if (new_dcp != SELECT_CHARSET_CANCEL)
571 const char *cpname;
572 char buf[BUF_TINY];
574 new_display_codepage = new_dcp;
575 cpname = (new_display_codepage == SELECT_CHARSET_OTHER_8BIT) ?
576 _("Other 8 bit") : codepages[new_display_codepage].name;
577 if (cpname != NULL)
578 utf8_display = str_isutf8 (cpname);
579 /* avoid strange bug with label repainting */
580 g_snprintf (buf, sizeof (buf), "%-27s", cpname);
581 label_set_text (cplabel, buf);
584 return 0;
587 static Dlg_head *
588 init_disp_bits_box (void)
590 /* dialog sizes */
591 const int DISPY = 11;
592 const int DISPX = 46;
594 const char *cpname;
595 Dlg_head *dbits_dlg;
597 do_refresh ();
599 dbits_dlg =
600 create_dlg (TRUE, 0, 0, DISPY, DISPX, dialog_colors, NULL,
601 "[Display bits]", _("Display bits"), DLG_CENTER | DLG_REVERSE);
603 add_widget (dbits_dlg, label_new (3, 4, _("Input / display codepage:")));
605 cpname = (new_display_codepage < 0) ? _("Other 8 bit") : codepages[new_display_codepage].name;
606 cplabel = label_new (4, 4, cpname);
607 add_widget (dbits_dlg, cplabel);
609 add_widget (dbits_dlg,
610 button_new (DISPY - 3, DISPX / 2 + 3, B_CANCEL, NORMAL_BUTTON, _("&Cancel"), 0));
611 add_widget (dbits_dlg, button_new (DISPY - 3, 7, B_ENTER, NORMAL_BUTTON, _("&OK"), 0));
613 inpcheck = check_new (6, 4, !use_8th_bit_as_meta, _("F&ull 8 bits input"));
614 add_widget (dbits_dlg, inpcheck);
616 cpname = _("&Select");
617 add_widget (dbits_dlg,
618 button_new (4, DISPX - 7 - str_term_width1 (cpname), B_USER,
619 NORMAL_BUTTON, cpname, sel_charset_button));
621 return dbits_dlg;
624 void
625 display_bits_box (void)
627 Dlg_head *dbits_dlg;
628 new_display_codepage = display_codepage;
630 application_keypad_mode ();
631 dbits_dlg = init_disp_bits_box ();
633 run_dlg (dbits_dlg);
635 if (dbits_dlg->ret_value == B_ENTER)
637 char *errmsg;
639 display_codepage = new_display_codepage;
640 errmsg = init_translation_table (source_codepage, display_codepage);
641 if (errmsg != NULL)
643 message (D_ERROR, MSG_ERROR, "%s", errmsg);
644 g_free (errmsg);
646 #ifdef HAVE_SLANG
647 tty_display_8bit (display_codepage != 0 && display_codepage != 1);
648 #else
649 tty_display_8bit (display_codepage != 0);
650 #endif
651 use_8th_bit_as_meta = !(inpcheck->state & C_BOOL);
653 destroy_dlg (dbits_dlg);
654 repaint_screen ();
657 #endif /* HAVE_CHARSET */
659 static cb_ret_t
660 tree_callback (Dlg_head * h, Widget * sender, dlg_msg_t msg, int parm, void *data)
662 switch (msg)
664 case DLG_POST_KEY:
665 /* The enter key will be processed by the tree widget */
666 if (parm == '\n')
668 h->ret_value = B_ENTER;
669 dlg_stop (h);
671 return MSG_HANDLED;
673 case DLG_ACTION:
674 /* command from buttonbar */
675 return send_message ((Widget *) find_tree (h), WIDGET_COMMAND, parm);
677 default:
678 return default_dlg_callback (h, sender, msg, parm, data);
682 /* Show tree in a box, not on a panel */
683 char *
684 tree_box (const char *current_dir)
686 WTree *mytree;
687 Dlg_head *dlg;
688 char *val = NULL;
689 WButtonBar *bar;
691 (void) current_dir;
693 /* Create the components */
694 dlg = create_dlg (TRUE, 0, 0, LINES - 9, COLS - 20, dialog_colors,
695 tree_callback, "[Directory Tree]",
696 _("Directory tree"), DLG_CENTER | DLG_REVERSE);
698 mytree = tree_new (2, 2, dlg->lines - 6, dlg->cols - 5, FALSE);
699 add_widget (dlg, mytree);
700 add_widget (dlg, hline_new (dlg->lines - 4, 1, -1));
701 bar = buttonbar_new (TRUE);
702 add_widget (dlg, bar);
703 /* restore ButtonBar coordinates after add_widget() */
704 ((Widget *) bar)->x = 0;
705 ((Widget *) bar)->y = LINES - 1;
707 if (run_dlg (dlg) == B_ENTER)
708 val = g_strdup (tree_selected_name (mytree));
710 destroy_dlg (dlg);
711 return val;
714 #ifdef ENABLE_VFS
716 static char *ret_timeout;
718 #ifdef USE_NETCODE
719 static char *ret_passwd;
720 static char *ret_directory_timeout;
721 static char *ret_ftp_proxy;
722 #endif
724 void
725 configure_vfs (void)
727 #define VFSX 56
729 #ifdef USE_NETCODE
730 #define VFSY 17
731 #else
732 #define VFSY 8
733 #endif
735 char buffer2[BUF_TINY];
736 #ifdef USE_NETCODE
737 char buffer3[BUF_TINY];
738 #endif
740 QuickWidget confvfs_widgets[] = {
741 /* 0 */ QUICK_BUTTON (30, VFSX, VFSY - 3, VFSY, N_("&Cancel"), B_CANCEL, NULL),
742 /* 1 */ QUICK_BUTTON (12, VFSX, VFSY - 3, VFSY, N_("&OK"), B_ENTER, NULL),
743 #ifdef USE_NETCODE
744 /* 2 */ QUICK_CHECKBOX (4, VFSX, 12, VFSY, N_("Use passive mode over pro&xy"),
745 &ftpfs_use_passive_connections_over_proxy),
746 /* 3 */ QUICK_CHECKBOX (4, VFSX, 11, VFSY, N_("Use &passive mode"),
747 &ftpfs_use_passive_connections),
748 /* 4 */ QUICK_CHECKBOX (4, VFSX, 10, VFSY, N_("&Use ~/.netrc"), &use_netrc),
749 /* 5 */ QUICK_INPUT (4, VFSX, 9, VFSY, ftpfs_proxy_host, 48, 0, "input-ftp-proxy",
750 &ret_ftp_proxy),
751 /* 6 */ QUICK_CHECKBOX (4, VFSX, 8, VFSY, N_("&Always use ftp proxy"),
752 &ftpfs_always_use_proxy),
753 /* 7 */ QUICK_LABEL (49, VFSX, 7, VFSY, N_("sec")),
754 /* 8 */ QUICK_INPUT (38, VFSX, 7, VFSY, buffer3, 10, 0, "input-timeout",
755 &ret_directory_timeout),
756 /* 9 */ QUICK_LABEL (4, VFSX, 7, VFSY, N_("ftpfs directory cache timeout:")),
757 /* 10 */ QUICK_INPUT (4, VFSX, 6, VFSY, ftpfs_anonymous_passwd, 48, 0, "input-passwd",
758 &ret_passwd),
759 /* 11 */ QUICK_LABEL (4, VFSX, 5, VFSY, N_("ftp anonymous password:")),
760 #endif
761 /* 12 */ QUICK_LABEL (49, VFSX, 3, VFSY, N_("sec")),
762 /* 13 */ QUICK_INPUT (38, VFSX, 3, VFSY, buffer2, 10, 0, "input-timo-vfs", &ret_timeout),
763 /* 14 */ QUICK_LABEL (4, VFSX, 3, VFSY, N_("Timeout for freeing VFSs:")),
764 QUICK_END
767 QuickDialog confvfs_dlg = {
768 VFSX, VFSY, -1, -1, N_("Virtual File System Setting"),
769 "[Virtual FS]", confvfs_widgets, FALSE
772 #ifdef USE_NETCODE
773 g_snprintf (buffer3, sizeof (buffer3), "%i", ftpfs_directory_timeout);
774 #endif
775 g_snprintf (buffer2, sizeof (buffer2), "%i", vfs_timeout);
777 if (quick_dialog (&confvfs_dlg) != B_CANCEL)
779 vfs_timeout = atoi (ret_timeout);
780 g_free (ret_timeout);
782 if (vfs_timeout < 0 || vfs_timeout > 10000)
783 vfs_timeout = 10;
784 #ifdef USE_NETCODE
785 g_free (ftpfs_anonymous_passwd);
786 ftpfs_anonymous_passwd = ret_passwd;
787 g_free (ftpfs_proxy_host);
788 ftpfs_proxy_host = ret_ftp_proxy;
789 ftpfs_directory_timeout = atoi (ret_directory_timeout);
790 g_free (ret_directory_timeout);
791 #endif
794 #undef VFSX
795 #undef VFSY
798 #endif /* ENABLE_VFS */
800 char *
801 cd_dialog (void)
803 const char *label = N_("cd");
804 const int ylen = 5;
805 const int xlen = 57;
807 int len;
809 #ifdef ENABLE_NLS
810 label = _(label);
811 #endif
813 len = str_term_width1 (label);
816 char *my_str;
818 QuickWidget quick_widgets[] = {
819 /* 0 */ QUICK_INPUT (4 + len, xlen, 2, ylen, "", xlen - 7 - len, 2, "input", &my_str),
820 /* 1 */ QUICK_LABEL (3, xlen, 2, ylen, label),
821 QUICK_END
824 QuickDialog Quick_input = {
825 xlen, ylen, 2, LINES - 2 - ylen, _("Quick cd"),
826 "[Quick cd]", quick_widgets, TRUE
829 return (quick_dialog (&Quick_input) != B_CANCEL) ? my_str : NULL;
833 void
834 symlink_dialog (const char *existing, const char *new, char **ret_existing, char **ret_new)
836 QuickWidget quick_widgets[] = {
837 /* 0 */ QUICK_BUTTON (50, 80, 6, 8, N_("&Cancel"), B_CANCEL, NULL),
838 /* 1 */ QUICK_BUTTON (16, 80, 6, 8, N_("&OK"), B_ENTER, NULL),
839 /* 2 */ QUICK_INPUT (4, 80, 5, 8, new, 58, 0, "input-1", ret_new),
840 /* 3 */ QUICK_LABEL (4, 80, 4, 8, N_("Symbolic link filename:")),
841 /* 4 */ QUICK_INPUT (4, 80, 3, 8, existing, 58, 0, "input-2", ret_existing),
842 /* 5 */ QUICK_LABEL (4, 80, 2, 8,
843 N_("Existing filename (filename symlink will point to):")),
844 QUICK_END
847 QuickDialog Quick_input = {
848 64, 12, -1, -1, N_("Symbolic link"),
849 "[File Menu]", quick_widgets, FALSE
852 if (quick_dialog (&Quick_input) == B_CANCEL)
854 *ret_new = NULL;
855 *ret_existing = NULL;
859 #ifdef WITH_BACKGROUND
860 #define B_STOP (B_USER+1)
861 #define B_RESUME (B_USER+2)
862 #define B_KILL (B_USER+3)
864 static int JOBS_X = 60;
865 #define JOBS_Y 15
866 static WListbox *bg_list;
867 static Dlg_head *jobs_dlg;
869 static void
870 jobs_fill_listbox (void)
872 static const char *state_str[2];
873 TaskList *tl = task_list;
875 if (!state_str[0])
877 state_str[0] = _("Running");
878 state_str[1] = _("Stopped");
881 while (tl)
883 char *s;
885 s = g_strconcat (state_str[tl->state], " ", tl->info, (char *) NULL);
886 listbox_add_item (bg_list, LISTBOX_APPEND_AT_END, 0, s, (void *) tl);
887 g_free (s);
888 tl = tl->next;
892 static int
893 task_cb (int action)
895 TaskList *tl;
896 int sig = 0;
898 if (!bg_list->list)
899 return 0;
901 /* Get this instance information */
902 listbox_get_current (bg_list, NULL, (void **) &tl);
904 # ifdef SIGTSTP
905 if (action == B_STOP)
907 sig = SIGSTOP;
908 tl->state = Task_Stopped;
910 else if (action == B_RESUME)
912 sig = SIGCONT;
913 tl->state = Task_Running;
915 else
916 # endif
917 if (action == B_KILL)
919 sig = SIGKILL;
922 if (sig == SIGKILL)
923 unregister_task_running (tl->pid, tl->fd);
925 kill (tl->pid, sig);
926 listbox_remove_list (bg_list);
927 jobs_fill_listbox ();
929 /* This can be optimized to just redraw this widget :-) */
930 dlg_redraw (jobs_dlg);
932 return 0;
935 static struct
937 const char *name;
938 int xpos;
939 int value;
940 int (*callback) (int);
942 job_buttons[] =
945 N_("&Stop"), 3, B_STOP, task_cb},
947 N_("&Resume"), 12, B_RESUME, task_cb},
949 N_("&Kill"), 23, B_KILL, task_cb},
951 N_("&OK"), 35, B_CANCEL, NULL}
954 void
955 jobs_cmd (void)
957 register int i;
958 int n_buttons = sizeof (job_buttons) / sizeof (job_buttons[0]);
960 #ifdef ENABLE_NLS
961 static int i18n_flag = 0;
962 if (!i18n_flag)
964 int startx = job_buttons[0].xpos;
965 int len;
967 for (i = 0; i < n_buttons; i++)
969 job_buttons[i].name = _(job_buttons[i].name);
971 len = str_term_width1 (job_buttons[i].name) + 4;
972 JOBS_X = max (JOBS_X, startx + len + 3);
974 job_buttons[i].xpos = startx;
975 startx += len;
978 /* Last button - Ok a.k.a. Cancel :) */
979 job_buttons[n_buttons - 1].xpos =
980 JOBS_X - str_term_width1 (job_buttons[n_buttons - 1].name) - 7;
982 i18n_flag = 1;
984 #endif /* ENABLE_NLS */
986 jobs_dlg = create_dlg (TRUE, 0, 0, JOBS_Y, JOBS_X, dialog_colors, NULL,
987 "[Background jobs]", _("Background Jobs"), DLG_CENTER | DLG_REVERSE);
989 bg_list = listbox_new (2, 3, JOBS_Y - 9, JOBS_X - 7, FALSE, NULL);
990 add_widget (jobs_dlg, bg_list);
992 i = n_buttons;
993 while (i--)
995 add_widget (jobs_dlg, button_new (JOBS_Y - 4,
996 job_buttons[i].xpos, job_buttons[i].value,
997 NORMAL_BUTTON, job_buttons[i].name,
998 job_buttons[i].callback));
1001 /* Insert all of task information in the list */
1002 jobs_fill_listbox ();
1003 run_dlg (jobs_dlg);
1005 destroy_dlg (jobs_dlg);
1007 #endif /* WITH_BACKGROUND */
1009 #ifdef ENABLE_VFS_SMB
1010 struct smb_authinfo *
1011 vfs_smb_get_authinfo (const char *host, const char *share, const char *domain, const char *user)
1013 static int dialog_x = 44;
1014 enum
1015 { b0 = 3, dialog_y = 12 };
1016 struct smb_authinfo *return_value;
1017 static const char *lc_labs[] = { N_("Domain:"), N_("Username:"), N_("Password:") };
1018 static const char *buts[] = { N_("&OK"), N_("&Cancel") };
1019 static int ilen = 30, istart = 14;
1020 static int b2 = 30;
1021 char *title;
1022 WInput *in_password;
1023 WInput *in_user;
1024 WInput *in_domain;
1025 Dlg_head *auth_dlg;
1027 const int input_colors[3] =
1029 INPUT_COLOR,
1030 INPUT_UNCHANGED_COLOR,
1031 INPUT_MARK_COLOR
1034 #ifdef ENABLE_NLS
1035 static int i18n_flag = 0;
1037 if (!i18n_flag)
1039 register int i = sizeof (lc_labs) / sizeof (lc_labs[0]);
1040 int l1, maxlen = 0;
1042 while (i--)
1044 l1 = str_term_width1 (lc_labs[i] = _(lc_labs[i]));
1045 if (l1 > maxlen)
1046 maxlen = l1;
1048 i = maxlen + ilen + 7;
1049 if (i > dialog_x)
1050 dialog_x = i;
1052 for (i = sizeof (buts) / sizeof (buts[0]), l1 = 0; i--;)
1054 l1 += str_term_width1 (buts[i] = _(buts[i]));
1056 l1 += 15;
1057 if (l1 > dialog_x)
1058 dialog_x = l1;
1060 ilen = dialog_x - 7 - maxlen; /* for the case of very long buttons :) */
1061 istart = dialog_x - 3 - ilen;
1063 b2 = dialog_x - (str_term_width1 (buts[1]) + 6);
1065 i18n_flag = 1;
1068 #endif /* ENABLE_NLS */
1070 if (!domain)
1071 domain = "";
1072 if (!user)
1073 user = "";
1075 title = g_strdup_printf (_("Password for \\\\%s\\%s"), host, share);
1077 auth_dlg = create_dlg (TRUE, 0, 0, dialog_y, dialog_x, dialog_colors, NULL,
1078 "[Smb Authinfo]", title, DLG_CENTER | DLG_REVERSE);
1080 g_free (title);
1082 in_user = input_new (5, istart, (int *) input_colors, ilen, user, "auth_name", INPUT_COMPLETE_DEFAULT);
1083 add_widget (auth_dlg, in_user);
1085 in_domain = input_new (3, istart, (int *) input_colors, ilen, domain, "auth_domain", INPUT_COMPLETE_DEFAULT);
1087 add_widget (auth_dlg, in_domain);
1088 add_widget (auth_dlg, button_new (9, b2, B_CANCEL, NORMAL_BUTTON, buts[1], 0));
1089 add_widget (auth_dlg, button_new (9, b0, B_ENTER, DEFPUSH_BUTTON, buts[0], 0));
1091 in_password = input_new (7, istart, (int *) input_colors, ilen, "", "auth_password", INPUT_COMPLETE_DEFAULT);
1093 in_password->completion_flags = 0;
1094 in_password->is_password = 1;
1095 add_widget (auth_dlg, in_password);
1097 add_widget (auth_dlg, label_new (7, 3, lc_labs[2]));
1098 add_widget (auth_dlg, label_new (5, 3, lc_labs[1]));
1099 add_widget (auth_dlg, label_new (3, 3, lc_labs[0]));
1101 run_dlg (auth_dlg);
1103 switch (auth_dlg->ret_value)
1105 case B_CANCEL:
1106 return_value = 0;
1107 break;
1108 default:
1109 return_value = g_try_new (struct smb_authinfo, 1);
1110 if (return_value)
1112 return_value->host = g_strdup (host);
1113 return_value->share = g_strdup (share);
1114 return_value->domain = g_strdup (in_domain->buffer);
1115 return_value->user = g_strdup (in_user->buffer);
1116 return_value->password = g_strdup (in_password->buffer);
1120 destroy_dlg (auth_dlg);
1122 return return_value;
1124 #endif /* ENABLE_VFS_SMB */