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