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