Ticket #2170: Color collisions
[midnight-commander.git] / src / boxes.c
blob208c7401f38c99781dea163812df896ce5021592
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/tty/key.h" /* XCTRL and ALT macros */
41 #include "lib/skin.h" /* INPUT_COLOR */
42 #include "lib/mcconfig.h" /* Load/save user formats */
43 #include "lib/strutil.h"
45 #include "lib/vfs/mc-vfs/vfs.h"
46 #ifdef ENABLE_VFS_FTP
47 #include "lib/vfs/mc-vfs/ftpfs.h"
48 #endif /* ENABLE_VFS_FTP */
49 #ifdef ENABLE_VFS_SMB
50 #include "lib/vfs/mc-vfs/smbfs.h"
51 #endif /* ENABLE_VFS_SMB */
53 #include "dialog.h" /* The nice dialog manager */
54 #include "widget.h" /* The widgets for the nice dialog manager */
55 #include "wtools.h"
56 #include "setup.h" /* For profile_name */
57 #include "command.h" /* For cmdline */
58 #include "dir.h"
59 #include "panel.h" /* LIST_TYPES */
60 #include "main.h" /* For the confirm_* variables */
61 #include "tree.h"
62 #include "layout.h" /* for get_nth_panel_name proto */
63 #include "background.h" /* task_list */
65 #ifdef HAVE_CHARSET
66 #include "charsets.h"
67 #include "selcodepage.h"
68 #endif
70 #include "boxes.h"
72 static WRadio *display_radio;
73 static WInput *display_user_format;
74 static WInput *display_mini_status;
75 static WCheck *display_check_status;
76 static char **displays_status;
77 static int display_user_hotkey = 'u';
79 static cb_ret_t
80 display_callback (Dlg_head * h, Widget * sender, dlg_msg_t msg, int parm, void *data)
82 switch (msg)
84 case DLG_KEY:
85 if (parm == '\n')
87 if (dlg_widget_active (display_radio))
89 assign_text (display_mini_status, displays_status[display_radio->sel]);
90 dlg_stop (h);
91 return MSG_HANDLED;
94 if (dlg_widget_active (display_user_format))
96 h->ret_value = B_USER + 6;
97 dlg_stop (h);
98 return MSG_HANDLED;
101 if (dlg_widget_active (display_mini_status))
103 h->ret_value = B_USER + 7;
104 dlg_stop (h);
105 return MSG_HANDLED;
109 if (g_ascii_tolower (parm) == display_user_hotkey)
111 display_radio->pos = display_radio->sel = 3;
112 dlg_select_widget (display_radio); /* force redraw */
113 h->callback (h, (Widget *) display_radio, DLG_ACTION, 0, NULL);
114 return MSG_HANDLED;
116 return MSG_NOT_HANDLED;
118 case DLG_ACTION:
119 if (sender == (Widget *) display_radio)
121 if (!(display_check_status->state & C_BOOL))
122 assign_text (display_mini_status, displays_status[display_radio->sel]);
123 update_input (display_mini_status, 0);
124 update_input (display_user_format, 0);
125 widget_disable (display_user_format->widget, display_radio->sel != 3);
126 return MSG_HANDLED;
129 if (sender == (Widget *) display_check_status)
131 if (display_check_status->state & C_BOOL)
133 widget_disable (display_mini_status->widget, FALSE);
134 assign_text (display_mini_status, displays_status[3]);
136 else
138 widget_disable (display_mini_status->widget, TRUE);
139 assign_text (display_mini_status, displays_status[display_radio->sel]);
141 update_input (display_mini_status, 0);
142 return MSG_HANDLED;
145 return MSG_NOT_HANDLED;
147 default:
148 return default_dlg_callback (h, sender, msg, parm, data);
152 static Dlg_head *
153 display_init (int radio_sel, char *init_text, int _check_status, char **_status)
155 int dlg_width = 48, dlg_height = 15;
156 Dlg_head *dd;
158 /* Controls whether the array strings have been translated */
159 const char *displays[LIST_TYPES] = {
160 N_("&Full file list"),
161 N_("&Brief file list"),
162 N_("&Long file list"),
163 N_("&User defined:")
166 /* Index in displays[] for "user defined" */
167 const int user_type_idx = 3;
169 const char *display_title = N_("Listing mode");
170 const char *user_mini_status = N_("User &mini status");
171 const char *ok_name = N_("&OK");
172 const char *cancel_name = N_("&Cancel");
174 WButton *ok_button, *cancel_button;
177 int i, maxlen = 0;
178 const char *cp;
179 int ok_len, cancel_len, b_len, gap;
181 #ifdef ENABLE_NLS
182 display_title = _(display_title);
183 user_mini_status = _(user_mini_status);
184 ok_name = _(ok_name);
185 cancel_name = _(cancel_name);
187 for (i = 0; i < LIST_TYPES; i++)
188 displays[i] = _(displays[i]);
189 #endif
191 /* get hotkey of user-defined format string */
192 cp = strchr (displays[user_type_idx], '&');
193 if (cp != NULL && *++cp != '\0')
194 display_user_hotkey = g_ascii_tolower (*cp);
196 /* xpos will be fixed later */
197 ok_button = button_new (dlg_height - 3, 0, B_ENTER, DEFPUSH_BUTTON, ok_name, 0);
198 ok_len = button_get_len (ok_button);
199 cancel_button = button_new (dlg_height - 3, 0, B_CANCEL, NORMAL_BUTTON, cancel_name, 0);
200 cancel_len = button_get_len (cancel_button);
201 b_len = ok_len + cancel_len + 2;
203 dlg_width = max (dlg_width, str_term_width1 (display_title) + 10);
204 /* calculate max width of radiobutons */
205 for (i = 0; i < LIST_TYPES; i++)
206 maxlen = max (maxlen, str_term_width1 (displays[i]));
207 dlg_width = max (dlg_width, maxlen);
208 dlg_width = max (dlg_width, str_term_width1 (user_mini_status) + 13);
210 /* buttons */
211 dlg_width = max (dlg_width, b_len + 6);
212 gap = (dlg_width - 6 - b_len) / 3;
213 ok_button->widget.x = 3 + gap;
214 cancel_button->widget.x = ok_button->widget.x + ok_len + gap + 2;
217 displays_status = _status;
219 dd = create_dlg (TRUE, 0, 0, dlg_height, dlg_width, dialog_colors,
220 display_callback, "[Listing Mode...]", display_title,
221 DLG_CENTER | DLG_REVERSE);
223 add_widget (dd, cancel_button);
224 add_widget (dd, ok_button);
226 display_mini_status = input_new (10, 8, input_get_default_colors(), dlg_width - 12, _status[radio_sel],
227 "mini-input", INPUT_COMPLETE_DEFAULT);
228 add_widget (dd, display_mini_status);
230 display_check_status = check_new (9, 4, _check_status, user_mini_status);
231 add_widget (dd, display_check_status);
233 display_user_format = input_new (7, 8, input_get_default_colors(), dlg_width - 12, init_text,
234 "user-fmt-input", INPUT_COMPLETE_DEFAULT);
235 add_widget (dd, display_user_format);
237 display_radio = radio_new (3, 4, LIST_TYPES, displays);
238 display_radio->sel = display_radio->pos = radio_sel;
239 add_widget (dd, display_radio);
241 return dd;
244 /* return list type */
246 display_box (WPanel * panel, char **userp, char **minip, int *use_msformat, int num)
248 int result = -1;
249 Dlg_head *dd;
250 char *section = NULL;
251 size_t i;
253 if (panel == NULL)
255 const char *p = get_nth_panel_name (num);
256 panel = g_new (WPanel, 1);
257 panel->list_type = list_full;
258 panel->user_format = g_strdup (DEFAULT_USER_FORMAT);
259 panel->user_mini_status = 0;
260 for (i = 0; i < LIST_TYPES; i++)
261 panel->user_status_format[i] = g_strdup (DEFAULT_USER_FORMAT);
262 section = g_strconcat ("Temporal:", p, (char *) NULL);
263 if (!mc_config_has_group (mc_main_config, section))
265 g_free (section);
266 section = g_strdup (p);
268 panel_load_setup (panel, section);
269 g_free (section);
272 dd = display_init (panel->list_type, panel->user_format,
273 panel->user_mini_status, panel->user_status_format);
275 if (run_dlg (dd) != B_CANCEL)
277 result = display_radio->sel;
278 *userp = g_strdup (display_user_format->buffer);
279 *minip = g_strdup (display_mini_status->buffer);
280 *use_msformat = display_check_status->state & C_BOOL;
283 if (section != NULL)
285 g_free (panel->user_format);
286 for (i = 0; i < LIST_TYPES; i++)
287 g_free (panel->user_status_format[i]);
288 g_free (panel);
291 destroy_dlg (dd);
293 return result;
296 const panel_field_t *
297 sort_box (const panel_field_t * sort_format, int *reverse, int *case_sensitive, int *exec_first)
299 int dlg_width = 40, dlg_height = 7;
301 const char **sort_orders_names;
302 gsize sort_names_num;
304 int sort_idx = 0;
306 const panel_field_t *result = sort_format;
308 sort_orders_names = panel_get_sortable_fields (&sort_names_num);
309 dlg_height += sort_names_num;
312 int max_radio = 0, max_check = 0;
313 int ok_len, cancel_len;
314 gsize i;
316 QuickWidget quick_widgets[] = {
317 /* 0 */
318 QUICK_BUTTON (0, dlg_width, dlg_height - 3, dlg_height, N_("&Cancel"), B_CANCEL, NULL),
319 /* 1 */
320 QUICK_BUTTON (0, dlg_width, dlg_height - 3, dlg_height, N_("&OK"), B_ENTER, NULL),
321 /* 2 */
322 QUICK_CHECKBOX (0, dlg_width, 5, dlg_height, N_("&Reverse"), reverse),
323 /* 3 */
324 QUICK_CHECKBOX (0, dlg_width, 4, dlg_height, N_("Case sensi&tive"), case_sensitive),
325 /* 4 */
326 QUICK_CHECKBOX (0, dlg_width, 3, dlg_height, N_("Executable &first"), exec_first),
327 /* 5 */
328 QUICK_RADIO (4, dlg_width, 3, dlg_height, 0,
329 NULL, &sort_idx),
330 QUICK_END
333 QuickDialog quick_dlg = {
334 dlg_width, dlg_height, -1, -1,
335 N_("Sort order"), "[Sort Order...]",
336 quick_widgets, NULL, TRUE
339 quick_widgets[5].u.radio.items = sort_orders_names;
340 quick_widgets[5].u.radio.count = sort_names_num;
342 for (i = 0; i < sort_names_num; i++)
343 if (strcmp (sort_orders_names[i], _(sort_format->title_hotkey)) == 0)
345 sort_idx = i;
346 break;
349 #ifdef ENABLE_NLS
350 quick_dlg.title = _(quick_dlg.title);
351 /* buttons */
352 for (i = 0; i < 2; i++)
353 quick_widgets[i].u.button.text = _(quick_widgets[i].u.button.text);
354 /* checkboxes */
355 for (i = 2; i < 5; i++)
356 quick_widgets[i].u.checkbox.text = _(quick_widgets[i].u.checkbox.text);
357 #endif /* ENABLE_NlS */
359 /* buttons */
360 cancel_len = str_term_width1 (quick_widgets[0].u.button.text) + 4;
361 ok_len = str_term_width1 (quick_widgets[1].u.button.text) + 6;
362 /* checkboxes */
363 for (i = 2; i < 5; i++)
364 max_check = max (max_check, str_term_width1 (quick_widgets[i].u.checkbox.text) + 4);
365 /* radiobuttons */
366 for (i = 0; i < sort_names_num; i++)
367 max_radio = max (max_radio, str_term_width1 (sort_orders_names[i]) + 4);
369 /* dialog width */
370 dlg_width = max (dlg_width, str_term_width1 (quick_dlg.title) + 8);
371 dlg_width = max (dlg_width, ok_len + cancel_len + 8);
372 dlg_width = max (dlg_width, 2 * max (max_radio, max_check) + 8);
374 /* fix widget and dialog parameters */
375 /* dialog */
376 quick_dlg.xlen = dlg_width;
377 /* widgets */
378 for (i = 0; (size_t) i < sizeof (quick_widgets) / sizeof (quick_widgets[0]) - 1; i++)
379 quick_widgets[i].x_divisions = dlg_width;
380 /* buttons */
381 quick_widgets[0].relative_x = dlg_width * 2 / 3 - cancel_len / 2;
382 quick_widgets[1].relative_x = dlg_width / 3 - ok_len / 2;
383 /* checkboxes */
384 for (i = 2; i < 5; i++)
385 quick_widgets[i].relative_x = dlg_width / 2 + 2;
387 if (quick_dialog (&quick_dlg) != B_CANCEL)
388 result = panel_get_field_by_title_hotkey (sort_orders_names[sort_idx]);
390 if (result == NULL)
391 result = sort_format;
393 g_strfreev ((gchar **) sort_orders_names);
394 return result;
398 void
399 confirm_box (void)
401 const char *title = _("Confirmation");
403 QuickWidget conf_widgets[] = {
404 /* 0 */ QUICK_BUTTON (29, 46, 10, 13, N_("&Cancel"), B_CANCEL, NULL),
405 /* 1 */ QUICK_BUTTON (12, 46, 10, 13, N_("&OK"), B_ENTER, NULL),
406 /* TRANSLATORS: no need to translate 'Confirmation', it's just a context prefix */
407 /* 2 */ QUICK_CHECKBOX (3, 46, 8, 13, N_("Confirmation|&History cleanup"),
408 &confirm_history_cleanup),
409 /* 3 */ QUICK_CHECKBOX (3, 46, 7, 13, N_("Confirmation|Di&rectory hotlist delete"),
410 &confirm_directory_hotlist_delete),
411 /* 4 */ QUICK_CHECKBOX (3, 46, 6, 13, N_("Confirmation|E&xit"), &confirm_exit),
412 /* 5 */ QUICK_CHECKBOX (3, 46, 5, 13, N_("Confirmation|&Execute"), &confirm_execute),
413 /* 6 */ QUICK_CHECKBOX (3, 46, 4, 13, N_("Confirmation|O&verwrite"), &confirm_overwrite),
414 /* 7 */ QUICK_CHECKBOX (3, 46, 3, 13, N_("Confirmation|&Delete"), &confirm_delete),
415 QUICK_END
418 const size_t w_num = sizeof (conf_widgets) / sizeof (conf_widgets[0]) - 1;
420 /* dialog sizes */
421 int dlg_width = 46;
422 int dlg_height = w_num + 5;
424 size_t i;
425 int maxlen = 0;
426 int cancel_len, ok_len, blen;
428 #ifdef ENABLE_NLS
429 title = _(title);
431 for (i = 0; i < 2; i++)
432 conf_widgets[i].u.button.text = _(conf_widgets[i].u.button.text);
433 #endif /* ENABLE_NLS */
435 for (i = 2; i < w_num; i++)
436 conf_widgets[i].u.checkbox.text = Q_ (conf_widgets[i].u.checkbox.text);
438 /* maximum length of checkboxes */
439 for (i = 2; i < w_num; i++)
440 maxlen = max (maxlen, str_term_width1 (conf_widgets[i].u.checkbox.text) + 4);
442 /* length of buttons */
443 cancel_len = str_term_width1 (conf_widgets[0].u.button.text) + 3;
444 ok_len = str_term_width1 (conf_widgets[1].u.button.text) + 5; /* default button */
446 blen = cancel_len + ok_len + 2;
448 dlg_width = max (maxlen, blen) + 6;
449 dlg_width = max (dlg_width, str_term_width1 (title) + 4);
451 /* correct widget parameters */
452 for (i = 0; i < w_num; i++)
454 conf_widgets[i].x_divisions = dlg_width;
455 conf_widgets[i].y_divisions = dlg_height;
458 conf_widgets[1].relative_x = dlg_width / 2 - blen / 2;
459 conf_widgets[0].relative_x = conf_widgets[1].relative_x + ok_len + 2;
462 QuickDialog confirmation = {
463 dlg_width, dlg_height, -1, -1, title,
464 "[Confirmation]", conf_widgets, NULL, TRUE
467 (void) quick_dialog (&confirmation);
472 #ifndef HAVE_CHARSET
473 void
474 display_bits_box (void) /* AB:FIXME: test dialog */
476 /* dialog sizes */
477 const int DISPY = 13;
478 const int DISPX = 46;
480 int new_meta = 0;
481 int current_mode;
483 const char *display_bits_str[] = {
484 N_("UTF-8 output"),
485 N_("Full 8 bits output"),
486 N_("ISO 8859-1"),
487 N_("7 bits")
490 QuickWidget display_widgets[] = {
491 /* 0 */ QUICK_BUTTON (15, DISPX, DISPY - 3, DISPY, N_("&Cancel"), B_CANCEL, NULL),
492 /* 1 */ QUICK_BUTTON (29, DISPX, DISPY - 3, DISPY, N_("&OK"), B_ENTER, NULL),
493 /* 2 */ QUICK_CHECKBOX (3, DISPX, 8, DISPY, N_("F&ull 8 bits input"), &new_meta),
494 /* 3 */ QUICK_RADIO (3, DISPX, 3, DISPY, 4, display_bits_str, &current_mode),
495 QUICK_END
498 QuickDialog display_bits = {
499 DISPX, DISPY, -1, -1, _("Display bits"),
500 "[Display bits]", display_widgets, NULL, TRUE
503 int i;
504 int l1, maxlen = 0;
505 int ok_len, cancel_len;
507 #ifdef ENABLE_NLS
508 static gboolean i18n_flag = FALSE;
510 if (!i18n_flag)
512 for (i = 0; i < 3; i++)
514 display_bits_str[i] = _(display_bits_str[i]);
517 display_widgets[0].u.button.text = _(display_widgets[0].u.button.text);
518 display_widgets[1].u.button.text = _(display_widgets[1].u.button.text);
519 display_widgets[2].u.checkbox.text = _(display_widgets[2].u.checkbox.text);
521 i18n_flag = TRUE;
523 #endif /* ENABLE_NLS */
525 /* radiobuttons */
526 for (i = 0; i < 3; i++)
527 maxlen = max (maxlen, str_term_width1 (display_bits_str[i]));
529 /* buttons */
530 cancel_len = str_term_width1 (display_widgets[0].u.button.text) + 2;
531 ok_len = str_term_width1 (display_widgets[1].u.button.text) + 4; /* default button */
533 l1 = max (cancel_len, ok_len);
535 display_bits.xlen = max (maxlen, l1) + 20;
537 for (i = 0; i < 4; i++)
538 display_widgets[i].x_divisions = display_bits.xlen;
540 display_widgets[0].relative_x = display_bits.xlen * 2 / 3 - cancel_len / 2;
541 display_widgets[1].relative_x = display_bits.xlen / 3 - ok_len / 2;
543 if (full_eight_bits)
544 current_mode = 0;
545 else if (eight_bit_clean)
546 current_mode = 1;
547 else
548 current_mode = 2;
550 new_meta = !use_8th_bit_as_meta;
552 if (quick_dialog (&display_bits) != B_CANCEL)
554 eight_bit_clean = current_mode < 3;
555 full_eight_bits = current_mode < 2;
556 #ifndef HAVE_SLANG
557 meta (stdscr, eight_bit_clean);
558 #else
559 SLsmg_Display_Eight_Bit = full_eight_bits ? 128 : 160;
560 #endif
561 use_8th_bit_as_meta = !new_meta;
565 #else /* HAVE_CHARSET */
567 static int new_display_codepage;
569 static WLabel *cplabel;
570 static WCheck *inpcheck;
572 static int
573 sel_charset_button (WButton *button, int action)
575 int new_dcp;
577 (void) button;
578 (void) action;
580 new_dcp = select_charset (-1, -1, new_display_codepage, TRUE);
582 if (new_dcp != SELECT_CHARSET_CANCEL)
584 const char *cpname;
585 char buf[BUF_TINY];
587 new_display_codepage = new_dcp;
588 cpname = (new_display_codepage == SELECT_CHARSET_OTHER_8BIT) ?
589 _("Other 8 bit") : codepages[new_display_codepage].name;
590 if (cpname != NULL)
591 utf8_display = str_isutf8 (cpname);
592 /* avoid strange bug with label repainting */
593 g_snprintf (buf, sizeof (buf), "%-27s", cpname);
594 label_set_text (cplabel, buf);
597 return 0;
600 static Dlg_head *
601 init_disp_bits_box (void)
603 /* dialog sizes */
604 const int DISPY = 11;
605 const int DISPX = 46;
607 const char *cpname;
608 Dlg_head *dbits_dlg;
610 do_refresh ();
612 dbits_dlg =
613 create_dlg (TRUE, 0, 0, DISPY, DISPX, dialog_colors, NULL,
614 "[Display bits]", _("Display bits"), DLG_CENTER | DLG_REVERSE);
616 add_widget (dbits_dlg, label_new (3, 4, _("Input / display codepage:")));
618 cpname = (new_display_codepage < 0) ? _("Other 8 bit") : codepages[new_display_codepage].name;
619 cplabel = label_new (4, 4, cpname);
620 add_widget (dbits_dlg, cplabel);
622 add_widget (dbits_dlg,
623 button_new (DISPY - 3, DISPX / 2 + 3, B_CANCEL, NORMAL_BUTTON, _("&Cancel"), 0));
624 add_widget (dbits_dlg, button_new (DISPY - 3, 7, B_ENTER, NORMAL_BUTTON, _("&OK"), 0));
626 inpcheck = check_new (6, 4, !use_8th_bit_as_meta, _("F&ull 8 bits input"));
627 add_widget (dbits_dlg, inpcheck);
629 cpname = _("&Select");
630 add_widget (dbits_dlg,
631 button_new (4, DISPX - 7 - str_term_width1 (cpname), B_USER,
632 NORMAL_BUTTON, cpname, sel_charset_button));
634 return dbits_dlg;
637 void
638 display_bits_box (void)
640 Dlg_head *dbits_dlg;
641 new_display_codepage = display_codepage;
643 application_keypad_mode ();
644 dbits_dlg = init_disp_bits_box ();
646 run_dlg (dbits_dlg);
648 if (dbits_dlg->ret_value == B_ENTER)
650 char *errmsg;
652 display_codepage = new_display_codepage;
653 errmsg = init_translation_table (source_codepage, display_codepage);
654 if (errmsg != NULL)
656 message (D_ERROR, MSG_ERROR, "%s", errmsg);
657 g_free (errmsg);
659 #ifdef HAVE_SLANG
660 tty_display_8bit (display_codepage != 0 && display_codepage != 1);
661 #else
662 tty_display_8bit (display_codepage != 0);
663 #endif
664 use_8th_bit_as_meta = !(inpcheck->state & C_BOOL);
666 destroy_dlg (dbits_dlg);
667 repaint_screen ();
670 #endif /* HAVE_CHARSET */
672 static cb_ret_t
673 tree_callback (Dlg_head * h, Widget * sender, dlg_msg_t msg, int parm, void *data)
675 switch (msg)
677 case DLG_POST_KEY:
678 /* The enter key will be processed by the tree widget */
679 if (parm == '\n')
681 h->ret_value = B_ENTER;
682 dlg_stop (h);
684 return MSG_HANDLED;
686 case DLG_ACTION:
687 /* command from buttonbar */
688 return send_message ((Widget *) find_tree (h), WIDGET_COMMAND, parm);
690 default:
691 return default_dlg_callback (h, sender, msg, parm, data);
695 /* Show tree in a box, not on a panel */
696 char *
697 tree_box (const char *current_dir)
699 WTree *mytree;
700 Dlg_head *dlg;
701 char *val = NULL;
702 WButtonBar *bar;
704 (void) current_dir;
706 /* Create the components */
707 dlg = create_dlg (TRUE, 0, 0, LINES - 9, COLS - 20, dialog_colors,
708 tree_callback, "[Directory Tree]",
709 _("Directory tree"), DLG_CENTER | DLG_REVERSE);
711 mytree = tree_new (2, 2, dlg->lines - 6, dlg->cols - 5, FALSE);
712 add_widget (dlg, mytree);
713 add_widget (dlg, hline_new (dlg->lines - 4, 1, -1));
714 bar = buttonbar_new (TRUE);
715 add_widget (dlg, bar);
716 /* restore ButtonBar coordinates after add_widget() */
717 ((Widget *) bar)->x = 0;
718 ((Widget *) bar)->y = LINES - 1;
720 if (run_dlg (dlg) == B_ENTER)
721 val = g_strdup (tree_selected_name (mytree));
723 destroy_dlg (dlg);
724 return val;
727 #ifdef ENABLE_VFS
729 static char *ret_timeout;
731 #ifdef ENABLE_VFS_FTP
732 static char *ret_ftp_proxy;
733 static char *ret_passwd;
734 static char *ret_directory_timeout;
736 static cb_ret_t
737 confvfs_callback (Dlg_head * h, Widget * sender, dlg_msg_t msg, int parm, void *data)
739 switch (msg)
741 case DLG_ACTION:
742 if (sender->id == 6)
744 /* message from "Always use ftp proxy" checkbutton */
745 const gboolean not_use = !(((WCheck *) sender)->state & C_BOOL);
746 Widget *w;
748 /* input */
749 w = dlg_find_by_id (h, sender->id - 1);
750 widget_disable (*w, not_use);
751 send_message (w, WIDGET_DRAW, 0);
753 return MSG_HANDLED;
755 return MSG_NOT_HANDLED;
757 default:
758 return default_dlg_callback (h, sender, msg, parm, data);
761 #endif /* ENABLE_VFS_FTP */
763 void
764 configure_vfs (void)
766 #define VFSX 56
768 #ifdef ENABLE_VFS_FTP
769 #define VFSY 17
770 #else
771 #define VFSY 8
772 #endif /* ENABLE_VFS_FTP */
774 char buffer2[BUF_TINY];
775 #ifdef ENABLE_VFS_FTP
776 char buffer3[BUF_TINY];
777 #endif
779 QuickWidget confvfs_widgets[] = {
780 /* 0 */ QUICK_BUTTON (30, VFSX, VFSY - 3, VFSY, N_("&Cancel"), B_CANCEL, NULL),
781 /* 1 */ QUICK_BUTTON (12, VFSX, VFSY - 3, VFSY, N_("&OK"), B_ENTER, NULL),
782 #ifdef ENABLE_VFS_FTP
783 /* 2 */ QUICK_CHECKBOX (4, VFSX, 12, VFSY, N_("Use passive mode over pro&xy"),
784 &ftpfs_use_passive_connections_over_proxy),
785 /* 3 */ QUICK_CHECKBOX (4, VFSX, 11, VFSY, N_("Use &passive mode"),
786 &ftpfs_use_passive_connections),
787 /* 4 */ QUICK_CHECKBOX (4, VFSX, 10, VFSY, N_("&Use ~/.netrc"), &ftpfs_use_netrc),
788 /* 5 */ QUICK_INPUT (4, VFSX, 9, VFSY, ftpfs_proxy_host, 48, 0, "input-ftp-proxy",
789 &ret_ftp_proxy),
790 /* 6 */ QUICK_CHECKBOX (4, VFSX, 8, VFSY, N_("&Always use ftp proxy"),
791 &ftpfs_always_use_proxy),
792 /* 7 */ QUICK_LABEL (49, VFSX, 7, VFSY, N_("sec")),
793 /* 8 */ QUICK_INPUT (38, VFSX, 7, VFSY, buffer3, 10, 0, "input-timeout",
794 &ret_directory_timeout),
795 /* 9 */ QUICK_LABEL (4, VFSX, 7, VFSY, N_("ftpfs directory cache timeout:")),
796 /* 10 */ QUICK_INPUT (4, VFSX, 6, VFSY, ftpfs_anonymous_passwd, 48, 0, "input-passwd",
797 &ret_passwd),
798 /* 11 */ QUICK_LABEL (4, VFSX, 5, VFSY, N_("ftp anonymous password:")),
799 #endif /* ENABLE_VFS_FTP */
800 /* 12 */ QUICK_LABEL (49, VFSX, 3, VFSY, N_("sec")),
801 /* 13 */ QUICK_INPUT (38, VFSX, 3, VFSY, buffer2, 10, 0, "input-timo-vfs", &ret_timeout),
802 /* 14 */ QUICK_LABEL (4, VFSX, 3, VFSY, N_("Timeout for freeing VFSs:")),
803 QUICK_END
806 QuickDialog confvfs_dlg = {
807 VFSX, VFSY, -1, -1, N_("Virtual File System Setting"),
808 "[Virtual FS]", confvfs_widgets,
809 #ifdef ENABLE_VFS_FTP
810 confvfs_callback,
811 #else
812 NULL,
813 #endif
814 FALSE
817 #ifdef ENABLE_VFS_FTP
818 g_snprintf (buffer3, sizeof (buffer3), "%i", ftpfs_directory_timeout);
820 if (!ftpfs_always_use_proxy)
821 confvfs_widgets[5].options = W_DISABLED;
822 #endif
824 g_snprintf (buffer2, sizeof (buffer2), "%i", vfs_timeout);
826 if (quick_dialog (&confvfs_dlg) != B_CANCEL)
828 vfs_timeout = atoi (ret_timeout);
829 g_free (ret_timeout);
831 if (vfs_timeout < 0 || vfs_timeout > 10000)
832 vfs_timeout = 10;
833 #ifdef ENABLE_VFS_FTP
834 g_free (ftpfs_anonymous_passwd);
835 ftpfs_anonymous_passwd = ret_passwd;
836 g_free (ftpfs_proxy_host);
837 ftpfs_proxy_host = ret_ftp_proxy;
838 ftpfs_directory_timeout = atoi (ret_directory_timeout);
839 g_free (ret_directory_timeout);
840 #endif
843 #undef VFSX
844 #undef VFSY
847 #endif /* ENABLE_VFS */
849 char *
850 cd_dialog (void)
852 const char *label = N_("cd");
853 const int ylen = 5;
854 const int xlen = 57;
856 int len;
858 #ifdef ENABLE_NLS
859 label = _(label);
860 #endif
862 len = str_term_width1 (label);
865 char *my_str;
867 QuickWidget quick_widgets[] = {
868 /* 0 */ QUICK_INPUT (4 + len, xlen, 2, ylen, "", xlen - 7 - len, 2, "input", &my_str),
869 /* 1 */ QUICK_LABEL (3, xlen, 2, ylen, label),
870 QUICK_END
873 QuickDialog Quick_input = {
874 xlen, ylen, 2, LINES - 2 - ylen, _("Quick cd"),
875 "[Quick cd]", quick_widgets, NULL, TRUE
878 return (quick_dialog (&Quick_input) != B_CANCEL) ? my_str : NULL;
882 void
883 symlink_dialog (const char *existing, const char *new, char **ret_existing, char **ret_new)
885 QuickWidget quick_widgets[] = {
886 /* 0 */ QUICK_BUTTON (50, 80, 6, 8, N_("&Cancel"), B_CANCEL, NULL),
887 /* 1 */ QUICK_BUTTON (16, 80, 6, 8, N_("&OK"), B_ENTER, NULL),
888 /* 2 */ QUICK_INPUT (4, 80, 5, 8, new, 58, 0, "input-1", ret_new),
889 /* 3 */ QUICK_LABEL (4, 80, 4, 8, N_("Symbolic link filename:")),
890 /* 4 */ QUICK_INPUT (4, 80, 3, 8, existing, 58, 0, "input-2", ret_existing),
891 /* 5 */ QUICK_LABEL (4, 80, 2, 8,
892 N_("Existing filename (filename symlink will point to):")),
893 QUICK_END
896 QuickDialog Quick_input = {
897 64, 12, -1, -1, N_("Symbolic link"),
898 "[File Menu]", quick_widgets, NULL, FALSE
901 if (quick_dialog (&Quick_input) == B_CANCEL)
903 *ret_new = NULL;
904 *ret_existing = NULL;
908 #ifdef WITH_BACKGROUND
909 #define B_STOP (B_USER+1)
910 #define B_RESUME (B_USER+2)
911 #define B_KILL (B_USER+3)
913 static int JOBS_X = 60;
914 #define JOBS_Y 15
915 static WListbox *bg_list;
916 static Dlg_head *jobs_dlg;
918 static void
919 jobs_fill_listbox (void)
921 static const char *state_str[2];
922 TaskList *tl = task_list;
924 if (!state_str[0])
926 state_str[0] = _("Running");
927 state_str[1] = _("Stopped");
930 while (tl)
932 char *s;
934 s = g_strconcat (state_str[tl->state], " ", tl->info, (char *) NULL);
935 listbox_add_item (bg_list, LISTBOX_APPEND_AT_END, 0, s, (void *) tl);
936 g_free (s);
937 tl = tl->next;
941 static int
942 task_cb (WButton *button, int action)
944 TaskList *tl;
945 int sig = 0;
947 (void) button;
949 if (bg_list->list == NULL)
950 return 0;
952 /* Get this instance information */
953 listbox_get_current (bg_list, NULL, (void **) &tl);
955 # ifdef SIGTSTP
956 if (action == B_STOP)
958 sig = SIGSTOP;
959 tl->state = Task_Stopped;
961 else if (action == B_RESUME)
963 sig = SIGCONT;
964 tl->state = Task_Running;
966 else
967 # endif
968 if (action == B_KILL)
970 sig = SIGKILL;
973 if (sig == SIGKILL)
974 unregister_task_running (tl->pid, tl->fd);
976 kill (tl->pid, sig);
977 listbox_remove_list (bg_list);
978 jobs_fill_listbox ();
980 /* This can be optimized to just redraw this widget :-) */
981 dlg_redraw (jobs_dlg);
983 return 0;
986 static struct
988 const char *name;
989 int xpos;
990 int value;
991 bcback callback;
993 job_buttons[] =
995 /* *INDENT-OFF* */
996 { N_("&Stop"), 3, B_STOP, task_cb },
997 { N_("&Resume"), 12, B_RESUME, task_cb },
998 { N_("&Kill"), 23, B_KILL, task_cb },
999 { N_("&OK"), 35, B_CANCEL, NULL }
1000 /* *INDENT-ON* */
1003 void
1004 jobs_cmd (void)
1006 register int i;
1007 int n_buttons = sizeof (job_buttons) / sizeof (job_buttons[0]);
1009 #ifdef ENABLE_NLS
1010 static int i18n_flag = 0;
1011 if (!i18n_flag)
1013 int startx = job_buttons[0].xpos;
1014 int len;
1016 for (i = 0; i < n_buttons; i++)
1018 job_buttons[i].name = _(job_buttons[i].name);
1020 len = str_term_width1 (job_buttons[i].name) + 4;
1021 JOBS_X = max (JOBS_X, startx + len + 3);
1023 job_buttons[i].xpos = startx;
1024 startx += len;
1027 /* Last button - Ok a.k.a. Cancel :) */
1028 job_buttons[n_buttons - 1].xpos =
1029 JOBS_X - str_term_width1 (job_buttons[n_buttons - 1].name) - 7;
1031 i18n_flag = 1;
1033 #endif /* ENABLE_NLS */
1035 jobs_dlg = create_dlg (TRUE, 0, 0, JOBS_Y, JOBS_X, dialog_colors, NULL,
1036 "[Background jobs]", _("Background Jobs"), DLG_CENTER | DLG_REVERSE);
1038 bg_list = listbox_new (2, 3, JOBS_Y - 9, JOBS_X - 7, FALSE, NULL);
1039 add_widget (jobs_dlg, bg_list);
1041 i = n_buttons;
1042 while (i--)
1044 add_widget (jobs_dlg, button_new (JOBS_Y - 4,
1045 job_buttons[i].xpos, job_buttons[i].value,
1046 NORMAL_BUTTON, job_buttons[i].name,
1047 job_buttons[i].callback));
1050 /* Insert all of task information in the list */
1051 jobs_fill_listbox ();
1052 run_dlg (jobs_dlg);
1054 destroy_dlg (jobs_dlg);
1056 #endif /* WITH_BACKGROUND */
1058 #ifdef ENABLE_VFS_SMB
1059 struct smb_authinfo *
1060 vfs_smb_get_authinfo (const char *host, const char *share, const char *domain, const char *user)
1062 static int dialog_x = 44;
1063 int b0 = 3, dialog_y = 12;
1064 static const char *lc_labs[] = { N_("Domain:"), N_("Username:"), N_("Password:") };
1065 static const char *buts[] = { N_("&OK"), N_("&Cancel") };
1066 static int ilen = 30, istart = 14;
1067 static int b2 = 30;
1068 char *title;
1069 WInput *in_password;
1070 WInput *in_user;
1071 WInput *in_domain;
1072 Dlg_head *auth_dlg;
1073 struct smb_authinfo *return_value = NULL;
1075 const int input_colors[3] =
1077 INPUT_COLOR,
1078 INPUT_UNCHANGED_COLOR,
1079 INPUT_MARK_COLOR
1082 #ifdef ENABLE_NLS
1083 static int i18n_flag = 0;
1085 if (!i18n_flag)
1087 register int i = sizeof (lc_labs) / sizeof (lc_labs[0]);
1088 int l1, maxlen = 0;
1090 while (i--)
1092 l1 = str_term_width1 (lc_labs[i] = _(lc_labs[i]));
1093 if (l1 > maxlen)
1094 maxlen = l1;
1096 i = maxlen + ilen + 7;
1097 if (i > dialog_x)
1098 dialog_x = i;
1100 for (i = sizeof (buts) / sizeof (buts[0]), l1 = 0; i--;)
1102 l1 += str_term_width1 (buts[i] = _(buts[i]));
1104 l1 += 15;
1105 if (l1 > dialog_x)
1106 dialog_x = l1;
1108 ilen = dialog_x - 7 - maxlen; /* for the case of very long buttons :) */
1109 istart = dialog_x - 3 - ilen;
1111 b2 = dialog_x - (str_term_width1 (buts[1]) + 6);
1113 i18n_flag = 1;
1116 #endif /* ENABLE_NLS */
1118 if (!domain)
1119 domain = "";
1120 if (!user)
1121 user = "";
1123 title = g_strdup_printf (_("Password for \\\\%s\\%s"), host, share);
1125 auth_dlg = create_dlg (TRUE, 0, 0, dialog_y, dialog_x, dialog_colors, NULL,
1126 "[Smb Authinfo]", title, DLG_CENTER | DLG_REVERSE);
1128 g_free (title);
1130 in_user = input_new (5, istart, input_get_default_colors(), ilen, user, "auth_name", INPUT_COMPLETE_DEFAULT);
1131 add_widget (auth_dlg, in_user);
1133 in_domain =
1134 input_new (3, istart, input_get_default_colors(), ilen, domain, "auth_domain", INPUT_COMPLETE_DEFAULT);
1136 add_widget (auth_dlg, in_domain);
1137 add_widget (auth_dlg, button_new (9, b2, B_CANCEL, NORMAL_BUTTON, buts[1], 0));
1138 add_widget (auth_dlg, button_new (9, b0, B_ENTER, DEFPUSH_BUTTON, buts[0], 0));
1140 in_password =
1141 input_new (7, istart, input_get_default_colors(), ilen, "", "auth_password", INPUT_COMPLETE_DEFAULT);
1143 in_password->completion_flags = 0;
1144 in_password->is_password = 1;
1145 add_widget (auth_dlg, in_password);
1147 add_widget (auth_dlg, label_new (7, 3, lc_labs[2]));
1148 add_widget (auth_dlg, label_new (5, 3, lc_labs[1]));
1149 add_widget (auth_dlg, label_new (3, 3, lc_labs[0]));
1151 if (run_dlg (auth_dlg) != B_CANCEL)
1152 return_value = vfs_smb_authinfo_new (host, share, in_domain->buffer, in_user->buffer,
1153 in_password->buffer);
1155 destroy_dlg (auth_dlg);
1157 return return_value;
1159 #endif /* ENABLE_VFS_SMB */