This source file includes following definitions.
- max
- check_split
- update_split
- b_left_right_cback
- bplus_cback
- bminus_cback
- layout_bg_callback
- layout_callback
- layout_dlg_create
- panel_do_cols
- restore_into_right_dir_panel
- layout_save
- layout_restore
- layout_change
- layout_box
- panel_update_cols
- setup_panels
- panels_split_equal
- panels_split_more
- panels_split_less
- setup_cmdline
- use_dash
- set_hintbar
- rotate_dash
- get_nth_panel_name
- create_panel
- swap_panels
- get_panel_type
- get_panel_widget
- get_current_index
- get_other_index
- get_other_panel
- get_current_type
- get_other_type
- save_panel_dir
- get_panel_dir_for
- do_load_prompt
- load_prompt
- title_path_prepare
- update_xterm_title_path
- update_terminal_cwd
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
33
34 #include <config.h>
35
36 #include <pwd.h>
37 #include <stdlib.h>
38 #include <stdio.h>
39 #include <string.h>
40 #include <sys/types.h>
41 #include <unistd.h>
42
43 #include "lib/global.h"
44 #include "lib/terminal.h"
45 #include "lib/tty/tty.h"
46 #include "lib/skin.h"
47 #include "lib/tty/key.h"
48 #include "lib/tty/mouse.h"
49 #include "lib/mcconfig.h"
50 #include "lib/vfs/vfs.h"
51 #include "lib/strutil.h"
52 #include "lib/widget.h"
53 #include "lib/event.h"
54 #include "lib/util.h"
55
56 #include "src/consaver/cons.saver.h"
57 #include "src/viewer/mcviewer.h"
58 #include "src/setup.h"
59 #ifdef ENABLE_SUBSHELL
60 #include "src/subshell/subshell.h"
61 #endif
62
63 #include "command.h"
64 #include "filemanager.h"
65 #include "tree.h"
66
67 #include "dir.h"
68 #include "layout.h"
69 #include "info.h"
70
71
72
73 panels_layout_t panels_layout = {
74
75 .horizontal_split = FALSE,
76
77
78 .vertical_equal = TRUE,
79 .left_panel_size = 0,
80
81
82 .horizontal_equal = TRUE,
83 .top_panel_size = 0
84 };
85
86
87 gboolean nice_rotating_dash = TRUE;
88
89
90 int output_lines = 0;
91
92
93 gboolean command_prompt = TRUE;
94
95
96 gboolean menubar_visible = TRUE;
97
98
99 gboolean xterm_title = TRUE;
100
101
102 gboolean free_space = TRUE;
103
104
105 int output_start_y = 0;
106
107 int ok_to_refresh = 1;
108
109
110
111
112
113
114 #define MAX_VIEWS 2
115
116
117 #define MINWIDTH 12
118 #define MINHEIGHT 5
119
120 #define B_2LEFT B_USER
121 #define B_2RIGHT (B_USER + 1)
122 #define B_PLUS (B_USER + 2)
123 #define B_MINUS (B_USER + 3)
124
125 #define LAYOUT_OPTIONS_COUNT G_N_ELEMENTS (check_options)
126
127
128
129 typedef struct
130 {
131 gboolean menubar_visible;
132 gboolean command_prompt;
133 gboolean keybar_visible;
134 gboolean message_visible;
135 gboolean xterm_title;
136 gboolean free_space;
137 int output_lines;
138 } layout_t;
139
140
141
142
143
144 static struct
145 {
146 panel_view_mode_t type;
147 Widget *widget;
148 char *last_saved_dir;
149 } panels[MAX_VIEWS] = {
150
151 { view_listing, NULL, NULL },
152 { view_listing, NULL, NULL },
153 };
154
155 static layout_t old_layout;
156 static panels_layout_t old_panels_layout;
157
158 static gboolean equal_split;
159 static int _output_lines;
160
161 static int height;
162
163 static WRadio *radio_widget;
164
165 static struct
166 {
167 const char *text;
168 gboolean *variable;
169 WCheck *widget;
170 } check_options[] = {
171 { N_ ("&Equal split"), &equal_split, NULL },
172 { N_ ("&Menubar visible"), &menubar_visible, NULL },
173 { N_ ("Command &prompt"), &command_prompt, NULL },
174 { N_ ("&Keybar visible"), &mc_global.keybar_visible, NULL },
175 { N_ ("H&intbar visible"), &mc_global.message_visible, NULL },
176 { N_ ("&XTerm window title"), &xterm_title, NULL },
177 { N_ ("&Show free space"), &free_space, NULL },
178 };
179
180 static const char *output_lines_label = NULL;
181 static int output_lines_label_len;
182
183 static WButton *bleft_widget, *bright_widget;
184
185
186
187
188
189
190 #undef max
191
192 static int
193 max (int a, int b)
194 {
195 return a > b ? a : b;
196 }
197
198
199
200 static void
201 check_split (panels_layout_t *layout)
202 {
203 if (layout->horizontal_split)
204 {
205 if (layout->horizontal_equal)
206 layout->top_panel_size = height / 2;
207 else if (layout->top_panel_size < MINHEIGHT)
208 layout->top_panel_size = MINHEIGHT;
209 else if (layout->top_panel_size > height - MINHEIGHT)
210 layout->top_panel_size = height - MINHEIGHT;
211 }
212 else
213 {
214 int md_cols = CONST_WIDGET (filemanager)->rect.cols;
215
216 if (layout->vertical_equal)
217 layout->left_panel_size = md_cols / 2;
218 else if (layout->left_panel_size < MINWIDTH)
219 layout->left_panel_size = MINWIDTH;
220 else if (layout->left_panel_size > md_cols - MINWIDTH)
221 layout->left_panel_size = md_cols - MINWIDTH;
222 }
223 }
224
225
226
227 static void
228 update_split (const WDialog *h)
229 {
230
231
232 check_split (&panels_layout);
233
234 if (panels_layout.horizontal_split)
235 check_options[0].widget->state = panels_layout.horizontal_equal;
236 else
237 check_options[0].widget->state = panels_layout.vertical_equal;
238 widget_draw (WIDGET (check_options[0].widget));
239
240 tty_setcolor (check_options[0].widget->state ? DISABLED_COLOR : COLOR_NORMAL);
241
242 widget_gotoyx (h, 6, 5);
243 if (panels_layout.horizontal_split)
244 tty_printf ("%03d", panels_layout.top_panel_size);
245 else
246 tty_printf ("%03d", panels_layout.left_panel_size);
247
248 widget_gotoyx (h, 6, 17);
249 if (panels_layout.horizontal_split)
250 tty_printf ("%03d", height - panels_layout.top_panel_size);
251 else
252 tty_printf ("%03d", CONST_WIDGET (filemanager)->rect.cols - panels_layout.left_panel_size);
253
254 widget_gotoyx (h, 6, 12);
255 tty_print_char ('=');
256 }
257
258
259
260 static int
261 b_left_right_cback (WButton *button, int action)
262 {
263 (void) action;
264
265 if (button == bright_widget)
266 {
267 if (panels_layout.horizontal_split)
268 panels_layout.top_panel_size++;
269 else
270 panels_layout.left_panel_size++;
271 }
272 else
273 {
274 if (panels_layout.horizontal_split)
275 panels_layout.top_panel_size--;
276 else
277 panels_layout.left_panel_size--;
278 }
279
280 update_split (DIALOG (WIDGET (button)->owner));
281 layout_change ();
282 do_refresh ();
283 return 0;
284 }
285
286
287
288 static int
289 bplus_cback (WButton *button, int action)
290 {
291 (void) button;
292 (void) action;
293
294 if (_output_lines < 99)
295 _output_lines++;
296 return 0;
297 }
298
299
300
301 static int
302 bminus_cback (WButton *button, int action)
303 {
304 (void) button;
305 (void) action;
306
307 if (_output_lines > 0)
308 _output_lines--;
309 return 0;
310 }
311
312
313
314 static cb_ret_t
315 layout_bg_callback (Widget *w, Widget *sender, widget_msg_t msg, int parm, void *data)
316 {
317 switch (msg)
318 {
319 case MSG_DRAW:
320 frame_callback (w, NULL, MSG_DRAW, 0, NULL);
321
322 old_layout.output_lines = -1;
323
324 update_split (DIALOG (w->owner));
325
326 if (old_layout.output_lines != _output_lines)
327 {
328 old_layout.output_lines = _output_lines;
329 tty_setcolor (mc_global.tty.console_flag != '\0' ? COLOR_NORMAL : DISABLED_COLOR);
330 widget_gotoyx (w, 9, 5);
331 tty_print_string (output_lines_label);
332 widget_gotoyx (w, 9, 5 + 3 + output_lines_label_len);
333 tty_printf ("%02d", _output_lines);
334 }
335 return MSG_HANDLED;
336
337 default:
338 return frame_callback (w, sender, msg, parm, data);
339 }
340 }
341
342
343
344 static cb_ret_t
345 layout_callback (Widget *w, Widget *sender, widget_msg_t msg, int parm, void *data)
346 {
347 WDialog *h = DIALOG (w);
348
349 switch (msg)
350 {
351 case MSG_POST_KEY:
352 {
353 const Widget *mw = CONST_WIDGET (filemanager);
354 gboolean _menubar_visible, _command_prompt, _keybar_visible, _message_visible;
355
356 _menubar_visible = check_options[1].widget->state;
357 _command_prompt = check_options[2].widget->state;
358 _keybar_visible = check_options[3].widget->state;
359 _message_visible = check_options[4].widget->state;
360
361 if (mc_global.tty.console_flag == '\0')
362 height = mw->rect.lines - (_keybar_visible ? 1 : 0) - (_command_prompt ? 1 : 0)
363 - (_menubar_visible ? 1 : 0) - _output_lines - (_message_visible ? 1 : 0);
364 else
365 {
366 int minimum;
367
368 if (_output_lines < 0)
369 _output_lines = 0;
370 height = mw->rect.lines - (_keybar_visible ? 1 : 0) - (_command_prompt ? 1 : 0)
371 - (_menubar_visible ? 1 : 0) - _output_lines - (_message_visible ? 1 : 0);
372 minimum = MINHEIGHT * (1 + (panels_layout.horizontal_split ? 1 : 0));
373 if (height < minimum)
374 {
375 _output_lines -= minimum - height;
376 height = minimum;
377 }
378 }
379
380 if (old_layout.output_lines != _output_lines)
381 {
382 old_layout.output_lines = _output_lines;
383 tty_setcolor (mc_global.tty.console_flag != '\0' ? COLOR_NORMAL : DISABLED_COLOR);
384 widget_gotoyx (h, 9, 5 + 3 + output_lines_label_len);
385 tty_printf ("%02d", _output_lines);
386 }
387 }
388 return MSG_HANDLED;
389
390 case MSG_NOTIFY:
391 if (sender == WIDGET (radio_widget))
392 {
393 if ((panels_layout.horizontal_split ? 1 : 0) == radio_widget->sel)
394 update_split (h);
395 else
396 {
397 int eq;
398
399 panels_layout.horizontal_split = radio_widget->sel != 0;
400
401 if (panels_layout.horizontal_split)
402 {
403 eq = panels_layout.horizontal_equal;
404 if (eq)
405 panels_layout.top_panel_size = height / 2;
406 }
407 else
408 {
409 eq = panels_layout.vertical_equal;
410 if (eq)
411 panels_layout.left_panel_size = CONST_WIDGET (filemanager)->rect.cols / 2;
412 }
413
414 widget_disable (WIDGET (bleft_widget), eq);
415 widget_disable (WIDGET (bright_widget), eq);
416
417 update_split (h);
418 layout_change ();
419 do_refresh ();
420 }
421
422 return MSG_HANDLED;
423 }
424
425 if (sender == WIDGET (check_options[0].widget))
426 {
427 gboolean eq;
428
429 if (panels_layout.horizontal_split)
430 {
431 panels_layout.horizontal_equal = check_options[0].widget->state;
432 eq = panels_layout.horizontal_equal;
433 }
434 else
435 {
436 panels_layout.vertical_equal = check_options[0].widget->state;
437 eq = panels_layout.vertical_equal;
438 }
439
440 widget_disable (WIDGET (bleft_widget), eq);
441 widget_disable (WIDGET (bright_widget), eq);
442
443 update_split (h);
444 layout_change ();
445 do_refresh ();
446
447 return MSG_HANDLED;
448 }
449
450 {
451 gboolean ok = TRUE;
452
453 if (sender == WIDGET (check_options[1].widget))
454 menubar_visible = check_options[1].widget->state;
455 else if (sender == WIDGET (check_options[2].widget))
456 command_prompt = check_options[2].widget->state;
457 else if (sender == WIDGET (check_options[3].widget))
458 mc_global.keybar_visible = check_options[3].widget->state;
459 else if (sender == WIDGET (check_options[4].widget))
460 mc_global.message_visible = check_options[4].widget->state;
461 else if (sender == WIDGET (check_options[5].widget))
462 xterm_title = check_options[5].widget->state;
463 else if (sender == WIDGET (check_options[6].widget))
464 free_space = check_options[6].widget->state;
465 else
466 ok = FALSE;
467
468 if (ok)
469 {
470 update_split (h);
471 layout_change ();
472 do_refresh ();
473 return MSG_HANDLED;
474 }
475 }
476
477 return MSG_NOT_HANDLED;
478
479 default:
480 return dlg_default_callback (w, sender, msg, parm, data);
481 }
482 }
483
484
485
486 static WDialog *
487 layout_dlg_create (void)
488 {
489 WDialog *layout_dlg;
490 WGroup *g;
491 int l1 = 0, width;
492 int b1, b2, b;
493 size_t i;
494
495 const char *title1 = _ ("Panel split");
496 const char *title2 = _ ("Console output");
497 const char *title3 = _ ("Other options");
498
499 const char *s_split_direction[2] = {
500 _ ("&Vertical"),
501 _ ("&Horizontal"),
502 };
503
504 const char *ok_button = _ ("&OK");
505 const char *cancel_button = _ ("&Cancel");
506
507 output_lines_label = _ ("Output lines:");
508
509 #ifdef ENABLE_NLS
510 {
511 static gboolean i18n = FALSE;
512
513 if (!i18n)
514 {
515 for (i = 0; i < (size_t) LAYOUT_OPTIONS_COUNT; i++)
516 check_options[i].text = _ (check_options[i].text);
517 i18n = TRUE;
518 }
519 }
520 #endif
521
522
523 i = G_N_ELEMENTS (s_split_direction);
524 while (i-- != 0)
525 l1 = max (l1, str_term_width1 (s_split_direction[i]) + 7);
526
527 for (i = 0; i < (size_t) LAYOUT_OPTIONS_COUNT; i++)
528 l1 = max (l1, str_term_width1 (check_options[i].text) + 7);
529
530 l1 = max (l1, str_term_width1 (title1) + 4);
531 l1 = max (l1, str_term_width1 (title2) + 4);
532 l1 = max (l1, str_term_width1 (title3) + 4);
533
534 output_lines_label_len = str_term_width1 (output_lines_label);
535 l1 = max (l1, output_lines_label_len + 12);
536
537 b1 = str_term_width1 (ok_button) + 5;
538 b2 = str_term_width1 (cancel_button) + 3;
539 b = b1 + b2 + 1;
540
541 width = max (l1 * 2 + 7, b);
542
543 layout_dlg = dlg_create (TRUE, 0, 0, 15, width, WPOS_CENTER, FALSE, dialog_colors,
544 layout_callback, NULL, "[Layout]", _ ("Layout"));
545 g = GROUP (layout_dlg);
546
547
548 layout_dlg->bg->callback = layout_bg_callback;
549
550 #define XTRACT(i) (*check_options[i].variable != 0), check_options[i].text
551
552
553 group_add_widget (g, groupbox_new (2, 3, 6, l1, title1));
554
555 radio_widget = radio_new (3, 5, 2, s_split_direction);
556 radio_widget->sel = panels_layout.horizontal_split ? 1 : 0;
557 group_add_widget (g, radio_widget);
558
559 check_options[0].widget = check_new (5, 5, XTRACT (0));
560 group_add_widget (g, check_options[0].widget);
561
562 equal_split = panels_layout.horizontal_split ? panels_layout.horizontal_equal
563 : panels_layout.vertical_equal;
564
565 bleft_widget = button_new (6, 8, B_2LEFT, NARROW_BUTTON, "&<", b_left_right_cback);
566 widget_disable (WIDGET (bleft_widget), equal_split);
567 group_add_widget (g, bleft_widget);
568
569 bright_widget = button_new (6, 14, B_2RIGHT, NARROW_BUTTON, "&>", b_left_right_cback);
570 widget_disable (WIDGET (bright_widget), equal_split);
571 group_add_widget (g, bright_widget);
572
573
574 {
575 widget_state_t disabled;
576 Widget *w;
577
578 disabled = mc_global.tty.console_flag != '\0' ? 0 : WST_DISABLED;
579
580 w = WIDGET (groupbox_new (8, 3, 3, l1, title2));
581 w->state |= disabled;
582 group_add_widget (g, w);
583
584 w = WIDGET (
585 button_new (9, output_lines_label_len + 5, B_PLUS, NARROW_BUTTON, "&+", bplus_cback));
586 w->state |= disabled;
587 group_add_widget (g, w);
588
589 w = WIDGET (button_new (9, output_lines_label_len + 5 + 5, B_MINUS, NARROW_BUTTON, "&-",
590 bminus_cback));
591 w->state |= disabled;
592 group_add_widget (g, w);
593 }
594
595
596 group_add_widget (g, groupbox_new (2, 4 + l1, 9, l1, title3));
597
598 for (i = 1; i < (size_t) LAYOUT_OPTIONS_COUNT; i++)
599 {
600 check_options[i].widget = check_new (i + 2, 6 + l1, XTRACT (i));
601 group_add_widget (g, check_options[i].widget);
602 }
603
604 #undef XTRACT
605
606 group_add_widget (g, hline_new (11, -1, -1));
607
608 group_add_widget (g, button_new (12, (width - b) / 2, B_ENTER, DEFPUSH_BUTTON, ok_button, 0));
609 group_add_widget (
610 g, button_new (12, (width - b) / 2 + b1 + 1, B_CANCEL, NORMAL_BUTTON, cancel_button, 0));
611
612 widget_select (WIDGET (radio_widget));
613
614 return layout_dlg;
615 }
616
617
618
619 static void
620 panel_do_cols (int idx)
621 {
622 if (get_panel_type (idx) == view_listing)
623 set_panel_formats (PANEL (panels[idx].widget));
624 else
625 panel_update_cols (panels[idx].widget, frame_half);
626 }
627
628
629
630
631 static Widget *
632 restore_into_right_dir_panel (int idx, gboolean last_was_panel, const WRect *r)
633 {
634 WPanel *new_widget;
635 const char *p_name;
636
637 p_name = get_nth_panel_name (idx);
638
639 if (last_was_panel)
640 {
641 vfs_path_t *saved_dir_vpath;
642
643 saved_dir_vpath = vfs_path_from_str (panels[idx].last_saved_dir);
644 new_widget = panel_sized_with_dir_new (p_name, r, saved_dir_vpath);
645 vfs_path_free (saved_dir_vpath, TRUE);
646 }
647 else
648 new_widget = panel_sized_new (p_name, r);
649
650 return WIDGET (new_widget);
651 }
652
653
654
655 static void
656 layout_save (void)
657 {
658 old_layout.menubar_visible = menubar_visible;
659 old_layout.command_prompt = command_prompt;
660 old_layout.keybar_visible = mc_global.keybar_visible;
661 old_layout.message_visible = mc_global.message_visible;
662 old_layout.xterm_title = xterm_title;
663 old_layout.free_space = free_space;
664 old_layout.output_lines = -1;
665
666 _output_lines = output_lines;
667
668 old_panels_layout = panels_layout;
669 }
670
671
672
673 static void
674 layout_restore (void)
675 {
676 menubar_visible = old_layout.menubar_visible;
677 command_prompt = old_layout.command_prompt;
678 mc_global.keybar_visible = old_layout.keybar_visible;
679 mc_global.message_visible = old_layout.message_visible;
680 xterm_title = old_layout.xterm_title;
681 free_space = old_layout.free_space;
682 output_lines = old_layout.output_lines;
683
684 panels_layout = old_panels_layout;
685 }
686
687
688
689
690
691 void
692 layout_change (void)
693 {
694 setup_panels ();
695
696
697
698 update_menu ();
699 load_hint (TRUE);
700 }
701
702
703
704 void
705 layout_box (void)
706 {
707 WDialog *layout_dlg;
708
709 layout_save ();
710
711 layout_dlg = layout_dlg_create ();
712
713 if (dlg_run (layout_dlg) == B_ENTER)
714 {
715 size_t i;
716
717 for (i = 0; i < (size_t) LAYOUT_OPTIONS_COUNT; i++)
718 if (check_options[i].widget != NULL)
719 *check_options[i].variable = check_options[i].widget->state;
720
721 output_lines = _output_lines;
722 }
723 else
724 layout_restore ();
725
726 widget_destroy (WIDGET (layout_dlg));
727 layout_change ();
728 do_refresh ();
729 }
730
731
732
733 void
734 panel_update_cols (Widget *widget, panel_display_t frame_size)
735 {
736 const Widget *mw = CONST_WIDGET (filemanager);
737 int cols, x;
738
739
740
741
742 if (widget->owner == NULL)
743 return;
744
745 if (panels_layout.horizontal_split)
746 {
747 widget->rect.cols = mw->rect.cols;
748 return;
749 }
750
751 if (frame_size == frame_full)
752 {
753 cols = mw->rect.cols;
754 x = mw->rect.x;
755 }
756 else if (widget == get_panel_widget (0))
757 {
758 cols = panels_layout.left_panel_size;
759 x = mw->rect.x;
760 }
761 else
762 {
763 cols = mw->rect.cols - panels_layout.left_panel_size;
764 x = mw->rect.x + panels_layout.left_panel_size;
765 }
766
767 widget->rect.cols = cols;
768 widget->rect.x = x;
769 }
770
771
772
773 void
774 setup_panels (void)
775 {
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802 Widget *mw = WIDGET (filemanager);
803 const WRect *r = &CONST_WIDGET (mw)->rect;
804 int start_y;
805 gboolean active;
806 WRect rb;
807
808 active = widget_get_state (mw, WST_ACTIVE);
809
810
811 if (active)
812 widget_set_state (mw, WST_SUSPENDED, TRUE);
813
814
815 height = r->lines - (menubar_visible ? 1 : 0) - (mc_global.message_visible ? 1 : 0)
816 - (command_prompt ? 1 : 0) - (mc_global.keybar_visible ? 1 : 0);
817
818 if (mc_global.tty.console_flag != '\0')
819 {
820 int minimum;
821
822 if (output_lines < 0)
823 output_lines = 0;
824 else
825 height -= output_lines;
826 minimum = MINHEIGHT * (1 + (panels_layout.horizontal_split ? 1 : 0));
827 if (height < minimum)
828 {
829 output_lines -= minimum - height;
830 height = minimum;
831 }
832 }
833
834 rb = *r;
835 rb.lines = 1;
836 widget_set_size_rect (WIDGET (the_menubar), &rb);
837 widget_set_visibility (WIDGET (the_menubar), menubar_visible);
838
839 check_split (&panels_layout);
840 start_y = r->y + (menubar_visible ? 1 : 0);
841
842
843 panel_do_cols (0);
844 panel_do_cols (1);
845
846
847 if (panels_layout.horizontal_split)
848 {
849 widget_set_size (panels[0].widget, start_y, r->x, panels_layout.top_panel_size,
850 panels[0].widget->rect.cols);
851 widget_set_size (panels[1].widget, start_y + panels_layout.top_panel_size, r->x,
852 height - panels_layout.top_panel_size, panels[1].widget->rect.cols);
853 }
854 else
855 {
856 widget_set_size (panels[0].widget, start_y, r->x, height, panels[0].widget->rect.cols);
857 widget_set_size (panels[1].widget, start_y, panels[1].widget->rect.x, height,
858 panels[1].widget->rect.cols);
859 }
860
861 widget_set_size (WIDGET (the_hint), height + start_y, r->x, 1, r->cols);
862 widget_set_visibility (WIDGET (the_hint), mc_global.message_visible);
863
864
865 if (mc_global.tty.console_flag != '\0' && output_lines != 0)
866 {
867 unsigned char end_line;
868
869 end_line = r->lines - (mc_global.keybar_visible ? 1 : 0) - 1;
870 output_start_y = end_line - (command_prompt ? 1 : 0) - output_lines + 1;
871 show_console_contents (output_start_y, end_line - output_lines, end_line);
872 }
873
874 if (command_prompt)
875 {
876 #ifdef ENABLE_SUBSHELL
877 if (!mc_global.tty.use_subshell || !do_load_prompt ())
878 #endif
879 setup_cmdline ();
880 }
881 else
882 {
883
884 widget_hide (WIDGET (cmdline));
885 widget_hide (WIDGET (the_prompt));
886 }
887
888 rb = *r;
889 rb.y = r->lines - 1;
890 rb.lines = 1;
891 widget_set_size_rect (WIDGET (the_bar), &rb);
892 widget_set_visibility (WIDGET (the_bar), mc_global.keybar_visible);
893
894 update_xterm_title_path ();
895 update_terminal_cwd ();
896
897
898 if (active)
899 {
900 widget_set_state (mw, WST_ACTIVE, TRUE);
901 widget_draw (mw);
902 }
903 }
904
905
906
907 void
908 panels_split_equal (void)
909 {
910 if (panels_layout.horizontal_split)
911 panels_layout.horizontal_equal = TRUE;
912 else
913 panels_layout.vertical_equal = TRUE;
914
915 layout_change ();
916 do_refresh ();
917 }
918
919
920
921 void
922 panels_split_more (void)
923 {
924 if (panels_layout.horizontal_split)
925 {
926 panels_layout.horizontal_equal = FALSE;
927 panels_layout.top_panel_size++;
928 }
929 else
930 {
931 panels_layout.vertical_equal = FALSE;
932 panels_layout.left_panel_size++;
933 }
934
935 layout_change ();
936 }
937
938
939
940 void
941 panels_split_less (void)
942 {
943 if (panels_layout.horizontal_split)
944 {
945 panels_layout.horizontal_equal = FALSE;
946 panels_layout.top_panel_size--;
947 }
948 else
949 {
950 panels_layout.vertical_equal = FALSE;
951 panels_layout.left_panel_size--;
952 }
953
954 layout_change ();
955 }
956
957
958
959 void
960 setup_cmdline (void)
961 {
962 const Widget *mw = CONST_WIDGET (filemanager);
963 const WRect *r = &mw->rect;
964 int prompt_width;
965 int y;
966
967 if (!command_prompt)
968 return;
969
970 #ifdef ENABLE_SUBSHELL
971 if (mc_global.tty.use_subshell)
972 {
973
974 if (subshell_prompt != NULL)
975 {
976 g_free (mc_prompt);
977 mc_prompt = g_strndup (subshell_prompt->str, subshell_prompt->len);
978 }
979
980 (void) strip_ctrl_codes (mc_prompt);
981 }
982 #endif
983
984 prompt_width = str_term_width1 (mc_prompt);
985
986
987 if (r->cols > 8 && prompt_width > r->cols - 8)
988 {
989 int prompt_len;
990
991 prompt_width = r->cols - 8;
992 prompt_len = str_offset_to_pos (mc_prompt, prompt_width);
993 mc_prompt[prompt_len] = '\0';
994 }
995
996 y = r->lines - 1 - (mc_global.keybar_visible ? 1 : 0);
997
998 widget_set_size (WIDGET (the_prompt), y, r->x, 1, prompt_width);
999 label_set_text (the_prompt, mc_prompt);
1000 widget_set_size (WIDGET (cmdline), y, r->x + prompt_width, 1, r->cols - prompt_width);
1001
1002 widget_show (WIDGET (the_prompt));
1003 widget_show (WIDGET (cmdline));
1004 }
1005
1006
1007
1008 void
1009 use_dash (gboolean flag)
1010 {
1011 if (flag)
1012 ok_to_refresh++;
1013 else
1014 ok_to_refresh--;
1015 }
1016
1017
1018
1019 void
1020 set_hintbar (const char *str)
1021 {
1022 label_set_text (the_hint, str);
1023 if (ok_to_refresh > 0)
1024 mc_refresh ();
1025 }
1026
1027
1028
1029 void
1030 rotate_dash (gboolean show)
1031 {
1032 static gint64 timestamp = 0;
1033
1034 static const gint64 delay = G_USEC_PER_SEC / 10;
1035
1036 const Widget *w = CONST_WIDGET (filemanager);
1037
1038 if (!nice_rotating_dash || (ok_to_refresh <= 0))
1039 return;
1040
1041 if (show && !mc_time_elapsed (×tamp, delay))
1042 return;
1043
1044 widget_gotoyx (w, menubar_visible ? 1 : 0, w->rect.cols - 1);
1045 tty_setcolor (NORMAL_COLOR);
1046
1047 if (!show)
1048 tty_print_alt_char (ACS_URCORNER, FALSE);
1049 else
1050 {
1051 static const char rotating_dash[4] MC_NONSTRING = "|/-\\";
1052 static size_t pos = 0;
1053
1054 tty_print_char (rotating_dash[pos]);
1055 pos = (pos + 1) % sizeof (rotating_dash);
1056 }
1057
1058 mc_refresh ();
1059 }
1060
1061
1062
1063 const char *
1064 get_nth_panel_name (int num)
1065 {
1066 if (num == 0)
1067 return "New Left Panel";
1068
1069 if (num == 1)
1070 return "New Right Panel";
1071
1072 {
1073 static char buffer[BUF_SMALL];
1074
1075 g_snprintf (buffer, sizeof (buffer), "%ith Panel", num);
1076 return buffer;
1077 }
1078 }
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093 void
1094 create_panel (int num, panel_view_mode_t type)
1095 {
1096 WRect r = { 0, 0, 0, 0 };
1097 unsigned int the_other = 0;
1098 Widget *new_widget = NULL, *old_widget = NULL;
1099 panel_view_mode_t old_type = view_listing;
1100
1101 if (num >= MAX_VIEWS)
1102 {
1103 fprintf (stderr, "Cannot allocate more that %d views\n", MAX_VIEWS);
1104 abort ();
1105 }
1106
1107 if (type != view_listing)
1108 {
1109 the_other = num == 0 ? 1 : 0;
1110
1111 if (panels[the_other].type != view_listing)
1112 return;
1113 }
1114
1115
1116 if (panels[num].widget != NULL)
1117 {
1118 Widget *w = panels[num].widget;
1119 WPanel *panel = PANEL (w);
1120
1121 r = w->rect;
1122 old_widget = w;
1123 old_type = panels[num].type;
1124
1125 if (old_type == view_listing && panel->frame_size == frame_full && type != view_listing)
1126 {
1127 int md_cols = CONST_WIDGET (filemanager)->rect.cols;
1128
1129 if (panels_layout.horizontal_split)
1130 {
1131 r.cols = md_cols;
1132 r.x = 0;
1133 }
1134 else
1135 {
1136 r.cols = md_cols - panels_layout.left_panel_size;
1137 if (num == 1)
1138 r.x = panels_layout.left_panel_size;
1139 }
1140 }
1141 }
1142
1143
1144
1145 if (old_widget == NULL && type != view_listing)
1146 panels[num].last_saved_dir = vfs_get_cwd ();
1147
1148 switch (type)
1149 {
1150 case view_nothing:
1151 case view_listing:
1152 {
1153 gboolean last_was_panel;
1154
1155 last_was_panel = old_widget != NULL && get_panel_type (num) != view_listing;
1156 new_widget = restore_into_right_dir_panel (num, last_was_panel, &r);
1157 break;
1158 }
1159
1160 case view_info:
1161 new_widget = WIDGET (info_new (&r));
1162 break;
1163
1164 case view_tree:
1165 new_widget = WIDGET (tree_new (&r, TRUE));
1166 break;
1167
1168 case view_quick:
1169 {
1170 WPanel *the_other_panel;
1171 const char *file_name = "";
1172
1173 new_widget = WIDGET (mcview_new (&r, TRUE));
1174 the_other_panel = PANEL (panels[the_other].widget);
1175 if (the_other_panel != NULL)
1176 {
1177 const file_entry_t *fe;
1178
1179 fe = panel_current_entry (the_other_panel);
1180 if (fe != NULL)
1181 file_name = fe->fname->str;
1182 }
1183
1184 mcview_load ((WView *) new_widget, 0, file_name, 0, 0, 0);
1185 break;
1186 }
1187
1188 default:
1189 break;
1190 }
1191
1192 if (type != view_listing)
1193
1194
1195 save_panel_dir (num);
1196
1197 panels[num].type = type;
1198 panels[num].widget = new_widget;
1199
1200
1201
1202 if (old_widget != NULL)
1203 {
1204 if (old_type == view_listing)
1205 {
1206
1207
1208 dlg_save_history (filemanager);
1209 }
1210
1211 widget_replace (old_widget, new_widget);
1212 }
1213
1214 if (type == view_listing)
1215 {
1216 WPanel *panel = PANEL (new_widget);
1217
1218
1219 if (old_widget != NULL)
1220 {
1221 ev_history_load_save_t event_data = { NULL, new_widget };
1222
1223 mc_event_raise (filemanager->event_group, MCEVENT_HISTORY_LOAD, &event_data);
1224 }
1225
1226 if (num == 0)
1227 left_panel = panel;
1228 else
1229 right_panel = panel;
1230
1231
1232 set_panel_formats (panel);
1233 }
1234
1235 if (type == view_tree)
1236 the_tree = (WTree *) new_widget;
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246 if ((type != view_listing) && (current_panel == PANEL (old_widget)))
1247 current_panel = num == 0 ? right_panel : left_panel;
1248
1249 g_free (old_widget);
1250 }
1251
1252
1253
1254
1255
1256
1257 void
1258 swap_panels (void)
1259 {
1260 WPanel *panel1, *panel2;
1261 Widget *tmp_widget;
1262
1263 panel1 = PANEL (panels[0].widget);
1264 panel2 = PANEL (panels[1].widget);
1265
1266 if (panels[0].type == view_listing && panels[1].type == view_listing
1267 && !mc_config_get_bool (mc_global.main_config, CONFIG_PANELS_SECTION, "simple_swap", FALSE))
1268 {
1269 WPanel panel;
1270
1271 #define panelswap(x) \
1272 panel.x = panel1->x; \
1273 panel1->x = panel2->x; \
1274 panel2->x = panel.x;
1275
1276 panelswap (dir);
1277 panelswap (active);
1278 panelswap (cwd_vpath);
1279 panelswap (lwd_vpath);
1280 panelswap (marked);
1281 panelswap (dirs_marked);
1282 panelswap (total);
1283 panelswap (top);
1284 panelswap (current);
1285 panelswap (is_panelized);
1286 panelswap (panelized_descr);
1287 panelswap (dir_stat);
1288 #undef panelswap
1289
1290 panel1->quick_search.active = FALSE;
1291 panel2->quick_search.active = FALSE;
1292
1293 if (current_panel == panel1)
1294 current_panel = panel2;
1295 else
1296 current_panel = panel1;
1297
1298
1299 if (memcmp (&panel1->sort_info, &panel2->sort_info, sizeof (dir_sort_options_t)) != 0)
1300 {
1301 panel_re_sort (other_panel);
1302 panel_re_sort (current_panel);
1303 }
1304
1305 if (widget_is_active (panels[0].widget))
1306 widget_select (panels[1].widget);
1307 else if (widget_is_active (panels[1].widget))
1308 widget_select (panels[0].widget);
1309 }
1310 else
1311 {
1312 WPanel *tmp_panel;
1313 WRect r;
1314 int tmp_type;
1315
1316 tmp_panel = right_panel;
1317 right_panel = left_panel;
1318 left_panel = tmp_panel;
1319
1320 if (panels[0].type == view_listing)
1321 {
1322 if (strcmp (panel1->name, get_nth_panel_name (0)) == 0)
1323 {
1324 g_free (panel1->name);
1325 panel1->name = g_strdup (get_nth_panel_name (1));
1326 }
1327 }
1328 if (panels[1].type == view_listing)
1329 {
1330 if (strcmp (panel2->name, get_nth_panel_name (1)) == 0)
1331 {
1332 g_free (panel2->name);
1333 panel2->name = g_strdup (get_nth_panel_name (0));
1334 }
1335 }
1336
1337 r = panels[0].widget->rect;
1338 panels[0].widget->rect = panels[1].widget->rect;
1339 panels[1].widget->rect = r;
1340
1341 tmp_widget = panels[0].widget;
1342 panels[0].widget = panels[1].widget;
1343 panels[1].widget = tmp_widget;
1344 tmp_type = panels[0].type;
1345 panels[0].type = panels[1].type;
1346 panels[1].type = tmp_type;
1347
1348
1349 if (panels[0].type == view_listing)
1350 set_panel_formats (PANEL (panels[0].widget));
1351 if (panels[1].type == view_listing)
1352 set_panel_formats (PANEL (panels[1].widget));
1353 }
1354 }
1355
1356
1357
1358 panel_view_mode_t
1359 get_panel_type (int idx)
1360 {
1361 return panels[idx].type;
1362 }
1363
1364
1365
1366 Widget *
1367 get_panel_widget (int idx)
1368 {
1369 return panels[idx].widget;
1370 }
1371
1372
1373
1374 int
1375 get_current_index (void)
1376 {
1377 return (panels[0].widget == WIDGET (current_panel) ? 0 : 1);
1378 }
1379
1380
1381
1382 int
1383 get_other_index (void)
1384 {
1385 return (get_current_index () == 0 ? 1 : 0);
1386 }
1387
1388
1389
1390 WPanel *
1391 get_other_panel (void)
1392 {
1393 return PANEL (get_panel_widget (get_other_index ()));
1394 }
1395
1396
1397
1398
1399 panel_view_mode_t
1400 get_current_type (void)
1401 {
1402 return (panels[0].widget == WIDGET (current_panel) ? panels[0].type : panels[1].type);
1403 }
1404
1405
1406
1407
1408 panel_view_mode_t
1409 get_other_type (void)
1410 {
1411 return (panels[0].widget == WIDGET (current_panel) ? panels[1].type : panels[0].type);
1412 }
1413
1414
1415
1416
1417 void
1418 save_panel_dir (int idx)
1419 {
1420 panel_view_mode_t type;
1421
1422 type = get_panel_type (idx);
1423 if (type == view_listing)
1424 {
1425 WPanel *p;
1426
1427 p = PANEL (get_panel_widget (idx));
1428 if (p != NULL)
1429 {
1430 g_free (panels[idx].last_saved_dir);
1431
1432 panels[idx].last_saved_dir = g_strdup (vfs_path_as_str (p->cwd_vpath));
1433 }
1434 }
1435 }
1436
1437
1438
1439
1440
1441 char *
1442 get_panel_dir_for (const WPanel *widget)
1443 {
1444 int i;
1445
1446 for (i = 0; i < MAX_VIEWS; i++)
1447 if (PANEL (get_panel_widget (i)) == widget)
1448 break;
1449
1450 if (i >= MAX_VIEWS)
1451 return g_strdup (".");
1452
1453 if (get_panel_type (i) == view_listing)
1454 {
1455 vfs_path_t *cwd_vpath;
1456
1457 cwd_vpath = PANEL (get_panel_widget (i))->cwd_vpath;
1458 return g_strdup (vfs_path_as_str (cwd_vpath));
1459 }
1460
1461 return g_strdup (panels[i].last_saved_dir);
1462 }
1463
1464
1465
1466 #ifdef ENABLE_SUBSHELL
1467 gboolean
1468 do_load_prompt (void)
1469 {
1470 gboolean ret = FALSE;
1471
1472 if (!read_subshell_prompt ())
1473 return ret;
1474
1475
1476 if (top_dlg != NULL && DIALOG (top_dlg->data) == filemanager && command_prompt)
1477 {
1478 setup_cmdline ();
1479
1480
1481
1482
1483
1484 widget_update_cursor (WIDGET (filemanager));
1485 mc_refresh ();
1486 ret = TRUE;
1487 }
1488 update_subshell_prompt = TRUE;
1489 return ret;
1490 }
1491
1492
1493
1494 int
1495 load_prompt (int fd, void *unused)
1496 {
1497 (void) fd;
1498 (void) unused;
1499
1500 if (should_read_new_subshell_prompt)
1501 do_load_prompt ();
1502 else
1503 flush_subshell (0, QUIETLY);
1504
1505 return 0;
1506 }
1507 #endif
1508
1509
1510
1511 void
1512 title_path_prepare (char **path, char **login)
1513 {
1514 char host[BUF_TINY];
1515 struct passwd *pw = NULL;
1516 int res = 0;
1517
1518 *path =
1519 vfs_path_to_str_flags (current_panel->cwd_vpath, 0, VPF_STRIP_HOME | VPF_STRIP_PASSWORD);
1520
1521 res = gethostname (host, sizeof (host));
1522 if (res != 0)
1523 host[0] = '\0';
1524 else
1525 host[sizeof (host) - 1] = '\0';
1526
1527 pw = getpwuid (getuid ());
1528 if (pw != NULL)
1529 *login = g_strdup_printf ("%s@%s", pw->pw_name, host);
1530 else
1531 *login = g_strdup (host);
1532 }
1533
1534
1535
1536
1537 void
1538 update_xterm_title_path (void)
1539 {
1540 if (mc_global.tty.xterm_flag && xterm_title)
1541 {
1542 char *p;
1543 char *path;
1544 char *login;
1545
1546 title_path_prepare (&path, &login);
1547
1548 p = g_strdup_printf ("mc [%s]:%s", login, path);
1549 g_free (login);
1550 g_free (path);
1551
1552 fprintf (stdout, ESC_STR "]0;%s" ESC_STR "\\", str_term_form (p));
1553 g_free (p);
1554
1555 if (!mc_global.tty.alternate_plus_minus)
1556 numeric_keypad_mode ();
1557 (void) fflush (stdout);
1558 }
1559 }
1560
1561
1562
1563
1564 void
1565 update_terminal_cwd (void)
1566 {
1567 if (mc_global.tty.xterm_flag && vfs_current_is_local ())
1568 {
1569 const gchar *host;
1570 char *path, *path_uri;
1571
1572 host = g_get_host_name ();
1573 path = vfs_path_to_str_flags (current_panel->cwd_vpath, 0, VPF_NONE);
1574 path_uri = g_uri_escape_string (path, "/", FALSE);
1575
1576 fprintf (stdout, ESC_STR "]7;file://%s%s" ESC_STR "\\", host, path_uri);
1577 (void) fflush (stdout);
1578
1579 g_free (path_uri);
1580 g_free (path);
1581 }
1582 }
1583
1584