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