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