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 = N_ ("Panel split");
496 const char *title2 = N_ ("Console output");
497 const char *title3 = N_ ("Other options");
498
499 const char *s_split_direction[2] = {
500 N_ ("&Vertical"),
501 N_ ("&Horizontal"),
502 };
503
504 const char *ok_button = N_ ("&OK");
505 const char *cancel_button = N_ ("&Cancel");
506
507 output_lines_label = _ ("Output lines:");
508
509 #ifdef ENABLE_NLS
510 {
511 static gboolean i18n = FALSE;
512
513 title1 = _ (title1);
514 title2 = _ (title2);
515 title3 = _ (title3);
516
517 i = G_N_ELEMENTS (s_split_direction);
518 while (i-- != 0)
519 s_split_direction[i] = _ (s_split_direction[i]);
520
521 if (!i18n)
522 {
523 for (i = 0; i < (size_t) LAYOUT_OPTIONS_COUNT; i++)
524 check_options[i].text = _ (check_options[i].text);
525 i18n = TRUE;
526 }
527
528 ok_button = _ (ok_button);
529 cancel_button = _ (cancel_button);
530 }
531 #endif
532
533
534 i = G_N_ELEMENTS (s_split_direction);
535 while (i-- != 0)
536 l1 = max (l1, str_term_width1 (s_split_direction[i]) + 7);
537
538 for (i = 0; i < (size_t) LAYOUT_OPTIONS_COUNT; i++)
539 l1 = max (l1, str_term_width1 (check_options[i].text) + 7);
540
541 l1 = max (l1, str_term_width1 (title1) + 4);
542 l1 = max (l1, str_term_width1 (title2) + 4);
543 l1 = max (l1, str_term_width1 (title3) + 4);
544
545 output_lines_label_len = str_term_width1 (output_lines_label);
546 l1 = max (l1, output_lines_label_len + 12);
547
548 b1 = str_term_width1 (ok_button) + 5;
549 b2 = str_term_width1 (cancel_button) + 3;
550 b = b1 + b2 + 1;
551
552 width = max (l1 * 2 + 7, b);
553
554 layout_dlg = dlg_create (TRUE, 0, 0, 15, width, WPOS_CENTER, FALSE, dialog_colors,
555 layout_callback, NULL, "[Layout]", _ ("Layout"));
556 g = GROUP (layout_dlg);
557
558
559 layout_dlg->bg->callback = layout_bg_callback;
560
561 #define XTRACT(i) (*check_options[i].variable != 0), check_options[i].text
562
563
564 group_add_widget (g, groupbox_new (2, 3, 6, l1, title1));
565
566 radio_widget = radio_new (3, 5, 2, s_split_direction);
567 radio_widget->sel = panels_layout.horizontal_split ? 1 : 0;
568 group_add_widget (g, radio_widget);
569
570 check_options[0].widget = check_new (5, 5, XTRACT (0));
571 group_add_widget (g, check_options[0].widget);
572
573 equal_split = panels_layout.horizontal_split ? panels_layout.horizontal_equal
574 : panels_layout.vertical_equal;
575
576 bleft_widget = button_new (6, 8, B_2LEFT, NARROW_BUTTON, "&<", b_left_right_cback);
577 widget_disable (WIDGET (bleft_widget), equal_split);
578 group_add_widget (g, bleft_widget);
579
580 bright_widget = button_new (6, 14, B_2RIGHT, NARROW_BUTTON, "&>", b_left_right_cback);
581 widget_disable (WIDGET (bright_widget), equal_split);
582 group_add_widget (g, bright_widget);
583
584
585 {
586 widget_state_t disabled;
587 Widget *w;
588
589 disabled = mc_global.tty.console_flag != '\0' ? 0 : WST_DISABLED;
590
591 w = WIDGET (groupbox_new (8, 3, 3, l1, title2));
592 w->state |= disabled;
593 group_add_widget (g, w);
594
595 w = WIDGET (
596 button_new (9, output_lines_label_len + 5, B_PLUS, NARROW_BUTTON, "&+", bplus_cback));
597 w->state |= disabled;
598 group_add_widget (g, w);
599
600 w = WIDGET (button_new (9, output_lines_label_len + 5 + 5, B_MINUS, NARROW_BUTTON, "&-",
601 bminus_cback));
602 w->state |= disabled;
603 group_add_widget (g, w);
604 }
605
606
607 group_add_widget (g, groupbox_new (2, 4 + l1, 9, l1, title3));
608
609 for (i = 1; i < (size_t) LAYOUT_OPTIONS_COUNT; i++)
610 {
611 check_options[i].widget = check_new (i + 2, 6 + l1, XTRACT (i));
612 group_add_widget (g, check_options[i].widget);
613 }
614
615 #undef XTRACT
616
617 group_add_widget (g, hline_new (11, -1, -1));
618
619 group_add_widget (g, button_new (12, (width - b) / 2, B_ENTER, DEFPUSH_BUTTON, ok_button, 0));
620 group_add_widget (
621 g, button_new (12, (width - b) / 2 + b1 + 1, B_CANCEL, NORMAL_BUTTON, cancel_button, 0));
622
623 widget_select (WIDGET (radio_widget));
624
625 return layout_dlg;
626 }
627
628
629
630 static void
631 panel_do_cols (int idx)
632 {
633 if (get_panel_type (idx) == view_listing)
634 set_panel_formats (PANEL (panels[idx].widget));
635 else
636 panel_update_cols (panels[idx].widget, frame_half);
637 }
638
639
640
641
642 static Widget *
643 restore_into_right_dir_panel (int idx, gboolean last_was_panel, const WRect *r)
644 {
645 WPanel *new_widget;
646 const char *p_name;
647
648 p_name = get_nth_panel_name (idx);
649
650 if (last_was_panel)
651 {
652 vfs_path_t *saved_dir_vpath;
653
654 saved_dir_vpath = vfs_path_from_str (panels[idx].last_saved_dir);
655 new_widget = panel_sized_with_dir_new (p_name, r, saved_dir_vpath);
656 vfs_path_free (saved_dir_vpath, TRUE);
657 }
658 else
659 new_widget = panel_sized_new (p_name, r);
660
661 return WIDGET (new_widget);
662 }
663
664
665
666 static void
667 layout_save (void)
668 {
669 old_layout.menubar_visible = menubar_visible;
670 old_layout.command_prompt = command_prompt;
671 old_layout.keybar_visible = mc_global.keybar_visible;
672 old_layout.message_visible = mc_global.message_visible;
673 old_layout.xterm_title = xterm_title;
674 old_layout.free_space = free_space;
675 old_layout.output_lines = -1;
676
677 _output_lines = output_lines;
678
679 old_panels_layout = panels_layout;
680 }
681
682
683
684 static void
685 layout_restore (void)
686 {
687 menubar_visible = old_layout.menubar_visible;
688 command_prompt = old_layout.command_prompt;
689 mc_global.keybar_visible = old_layout.keybar_visible;
690 mc_global.message_visible = old_layout.message_visible;
691 xterm_title = old_layout.xterm_title;
692 free_space = old_layout.free_space;
693 output_lines = old_layout.output_lines;
694
695 panels_layout = old_panels_layout;
696 }
697
698
699
700
701
702 void
703 layout_change (void)
704 {
705 setup_panels ();
706
707
708
709 update_menu ();
710 load_hint (TRUE);
711 }
712
713
714
715 void
716 layout_box (void)
717 {
718 WDialog *layout_dlg;
719
720 layout_save ();
721
722 layout_dlg = layout_dlg_create ();
723
724 if (dlg_run (layout_dlg) == B_ENTER)
725 {
726 size_t i;
727
728 for (i = 0; i < (size_t) LAYOUT_OPTIONS_COUNT; i++)
729 if (check_options[i].widget != NULL)
730 *check_options[i].variable = check_options[i].widget->state;
731
732 output_lines = _output_lines;
733 }
734 else
735 layout_restore ();
736
737 widget_destroy (WIDGET (layout_dlg));
738 layout_change ();
739 do_refresh ();
740 }
741
742
743
744 void
745 panel_update_cols (Widget *widget, panel_display_t frame_size)
746 {
747 const Widget *mw = CONST_WIDGET (filemanager);
748 int cols, x;
749
750
751
752
753 if (widget->owner == NULL)
754 return;
755
756 if (panels_layout.horizontal_split)
757 {
758 widget->rect.cols = mw->rect.cols;
759 return;
760 }
761
762 if (frame_size == frame_full)
763 {
764 cols = mw->rect.cols;
765 x = mw->rect.x;
766 }
767 else if (widget == get_panel_widget (0))
768 {
769 cols = panels_layout.left_panel_size;
770 x = mw->rect.x;
771 }
772 else
773 {
774 cols = mw->rect.cols - panels_layout.left_panel_size;
775 x = mw->rect.x + panels_layout.left_panel_size;
776 }
777
778 widget->rect.cols = cols;
779 widget->rect.x = x;
780 }
781
782
783
784 void
785 setup_panels (void)
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
813 Widget *mw = WIDGET (filemanager);
814 const WRect *r = &CONST_WIDGET (mw)->rect;
815 int start_y;
816 gboolean active;
817 WRect rb;
818
819 active = widget_get_state (mw, WST_ACTIVE);
820
821
822 if (active)
823 widget_set_state (mw, WST_SUSPENDED, TRUE);
824
825
826 height = r->lines - (menubar_visible ? 1 : 0) - (mc_global.message_visible ? 1 : 0)
827 - (command_prompt ? 1 : 0) - (mc_global.keybar_visible ? 1 : 0);
828
829 if (mc_global.tty.console_flag != '\0')
830 {
831 int minimum;
832
833 if (output_lines < 0)
834 output_lines = 0;
835 else
836 height -= output_lines;
837 minimum = MINHEIGHT * (1 + (panels_layout.horizontal_split ? 1 : 0));
838 if (height < minimum)
839 {
840 output_lines -= minimum - height;
841 height = minimum;
842 }
843 }
844
845 rb = *r;
846 rb.lines = 1;
847 widget_set_size_rect (WIDGET (the_menubar), &rb);
848 widget_set_visibility (WIDGET (the_menubar), menubar_visible);
849
850 check_split (&panels_layout);
851 start_y = r->y + (menubar_visible ? 1 : 0);
852
853
854 panel_do_cols (0);
855 panel_do_cols (1);
856
857
858 if (panels_layout.horizontal_split)
859 {
860 widget_set_size (panels[0].widget, start_y, r->x, panels_layout.top_panel_size,
861 panels[0].widget->rect.cols);
862 widget_set_size (panels[1].widget, start_y + panels_layout.top_panel_size, r->x,
863 height - panels_layout.top_panel_size, panels[1].widget->rect.cols);
864 }
865 else
866 {
867 widget_set_size (panels[0].widget, start_y, r->x, height, panels[0].widget->rect.cols);
868 widget_set_size (panels[1].widget, start_y, panels[1].widget->rect.x, height,
869 panels[1].widget->rect.cols);
870 }
871
872 widget_set_size (WIDGET (the_hint), height + start_y, r->x, 1, r->cols);
873 widget_set_visibility (WIDGET (the_hint), mc_global.message_visible);
874
875
876 if (mc_global.tty.console_flag != '\0' && output_lines != 0)
877 {
878 unsigned char end_line;
879
880 end_line = r->lines - (mc_global.keybar_visible ? 1 : 0) - 1;
881 output_start_y = end_line - (command_prompt ? 1 : 0) - output_lines + 1;
882 show_console_contents (output_start_y, end_line - output_lines, end_line);
883 }
884
885 if (command_prompt)
886 {
887 #ifdef ENABLE_SUBSHELL
888 if (!mc_global.tty.use_subshell || !do_load_prompt ())
889 #endif
890 setup_cmdline ();
891 }
892 else
893 {
894
895 widget_hide (WIDGET (cmdline));
896 widget_hide (WIDGET (the_prompt));
897 }
898
899 rb = *r;
900 rb.y = r->lines - 1;
901 rb.lines = 1;
902 widget_set_size_rect (WIDGET (the_bar), &rb);
903 widget_set_visibility (WIDGET (the_bar), mc_global.keybar_visible);
904
905 update_xterm_title_path ();
906 update_terminal_cwd ();
907
908
909 if (active)
910 {
911 widget_set_state (mw, WST_ACTIVE, TRUE);
912 widget_draw (mw);
913 }
914 }
915
916
917
918 void
919 panels_split_equal (void)
920 {
921 if (panels_layout.horizontal_split)
922 panels_layout.horizontal_equal = TRUE;
923 else
924 panels_layout.vertical_equal = TRUE;
925
926 layout_change ();
927 do_refresh ();
928 }
929
930
931
932 void
933 panels_split_more (void)
934 {
935 if (panels_layout.horizontal_split)
936 {
937 panels_layout.horizontal_equal = FALSE;
938 panels_layout.top_panel_size++;
939 }
940 else
941 {
942 panels_layout.vertical_equal = FALSE;
943 panels_layout.left_panel_size++;
944 }
945
946 layout_change ();
947 }
948
949
950
951 void
952 panels_split_less (void)
953 {
954 if (panels_layout.horizontal_split)
955 {
956 panels_layout.horizontal_equal = FALSE;
957 panels_layout.top_panel_size--;
958 }
959 else
960 {
961 panels_layout.vertical_equal = FALSE;
962 panels_layout.left_panel_size--;
963 }
964
965 layout_change ();
966 }
967
968
969
970 void
971 setup_cmdline (void)
972 {
973 const Widget *mw = CONST_WIDGET (filemanager);
974 const WRect *r = &mw->rect;
975 int prompt_width;
976 int y;
977 char *tmp_prompt = (char *) mc_prompt;
978
979 if (!command_prompt)
980 return;
981
982 #ifdef ENABLE_SUBSHELL
983 if (mc_global.tty.use_subshell)
984 {
985
986 if (subshell_prompt != NULL)
987 tmp_prompt = g_string_free (subshell_prompt, FALSE);
988 else
989 tmp_prompt = g_strdup (mc_prompt);
990 (void) strip_ctrl_codes (tmp_prompt);
991 }
992 #endif
993
994 prompt_width = str_term_width1 (tmp_prompt);
995
996
997 if (r->cols > 8 && prompt_width > r->cols - 8)
998 {
999 int prompt_len;
1000
1001 prompt_width = r->cols - 8;
1002 prompt_len = str_offset_to_pos (tmp_prompt, prompt_width);
1003 tmp_prompt[prompt_len] = '\0';
1004 }
1005
1006 #ifdef ENABLE_SUBSHELL
1007 if (mc_global.tty.use_subshell)
1008 {
1009 subshell_prompt = g_string_new_take (tmp_prompt);
1010 mc_prompt = subshell_prompt->str;
1011 }
1012 #endif
1013
1014 y = r->lines - 1 - (mc_global.keybar_visible ? 1 : 0);
1015
1016 widget_set_size (WIDGET (the_prompt), y, r->x, 1, prompt_width);
1017 label_set_text (the_prompt, mc_prompt);
1018 widget_set_size (WIDGET (cmdline), y, r->x + prompt_width, 1, r->cols - prompt_width);
1019
1020 widget_show (WIDGET (the_prompt));
1021 widget_show (WIDGET (cmdline));
1022 }
1023
1024
1025
1026 void
1027 use_dash (gboolean flag)
1028 {
1029 if (flag)
1030 ok_to_refresh++;
1031 else
1032 ok_to_refresh--;
1033 }
1034
1035
1036
1037 void
1038 set_hintbar (const char *str)
1039 {
1040 label_set_text (the_hint, str);
1041 if (ok_to_refresh > 0)
1042 mc_refresh ();
1043 }
1044
1045
1046
1047 void
1048 rotate_dash (gboolean show)
1049 {
1050 static gint64 timestamp = 0;
1051
1052 static const gint64 delay = G_USEC_PER_SEC / 10;
1053
1054 const Widget *w = CONST_WIDGET (filemanager);
1055
1056 if (!nice_rotating_dash || (ok_to_refresh <= 0))
1057 return;
1058
1059 if (show && !mc_time_elapsed (×tamp, delay))
1060 return;
1061
1062 widget_gotoyx (w, menubar_visible ? 1 : 0, w->rect.cols - 1);
1063 tty_setcolor (NORMAL_COLOR);
1064
1065 if (!show)
1066 tty_print_alt_char (ACS_URCORNER, FALSE);
1067 else
1068 {
1069 static const char rotating_dash[4] = "|/-\\";
1070 static size_t pos = 0;
1071
1072 tty_print_char (rotating_dash[pos]);
1073 pos = (pos + 1) % sizeof (rotating_dash);
1074 }
1075
1076 mc_refresh ();
1077 }
1078
1079
1080
1081 const char *
1082 get_nth_panel_name (int num)
1083 {
1084 if (num == 0)
1085 return "New Left Panel";
1086
1087 if (num == 1)
1088 return "New Right Panel";
1089
1090 {
1091 static char buffer[BUF_SMALL];
1092
1093 g_snprintf (buffer, sizeof (buffer), "%ith Panel", num);
1094 return buffer;
1095 }
1096 }
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111 void
1112 create_panel (int num, panel_view_mode_t type)
1113 {
1114 WRect r = { 0, 0, 0, 0 };
1115 unsigned int the_other = 0;
1116 Widget *new_widget = NULL, *old_widget = NULL;
1117 panel_view_mode_t old_type = view_listing;
1118
1119 if (num >= MAX_VIEWS)
1120 {
1121 fprintf (stderr, "Cannot allocate more that %d views\n", MAX_VIEWS);
1122 abort ();
1123 }
1124
1125 if (type != view_listing)
1126 {
1127 the_other = num == 0 ? 1 : 0;
1128
1129 if (panels[the_other].type != view_listing)
1130 return;
1131 }
1132
1133
1134 if (panels[num].widget != NULL)
1135 {
1136 Widget *w = panels[num].widget;
1137 WPanel *panel = PANEL (w);
1138
1139 r = w->rect;
1140 old_widget = w;
1141 old_type = panels[num].type;
1142
1143 if (old_type == view_listing && panel->frame_size == frame_full && type != view_listing)
1144 {
1145 int md_cols = CONST_WIDGET (filemanager)->rect.cols;
1146
1147 if (panels_layout.horizontal_split)
1148 {
1149 r.cols = md_cols;
1150 r.x = 0;
1151 }
1152 else
1153 {
1154 r.cols = md_cols - panels_layout.left_panel_size;
1155 if (num == 1)
1156 r.x = panels_layout.left_panel_size;
1157 }
1158 }
1159 }
1160
1161
1162
1163 if (old_widget == NULL && type != view_listing)
1164 panels[num].last_saved_dir = vfs_get_cwd ();
1165
1166 switch (type)
1167 {
1168 case view_nothing:
1169 case view_listing:
1170 {
1171 gboolean last_was_panel;
1172
1173 last_was_panel = old_widget != NULL && get_panel_type (num) != view_listing;
1174 new_widget = restore_into_right_dir_panel (num, last_was_panel, &r);
1175 break;
1176 }
1177
1178 case view_info:
1179 new_widget = WIDGET (info_new (&r));
1180 break;
1181
1182 case view_tree:
1183 new_widget = WIDGET (tree_new (&r, TRUE));
1184 break;
1185
1186 case view_quick:
1187 {
1188 WPanel *the_other_panel;
1189 const char *file_name = "";
1190
1191 new_widget = WIDGET (mcview_new (&r, TRUE));
1192 the_other_panel = PANEL (panels[the_other].widget);
1193 if (the_other_panel != NULL)
1194 {
1195 const file_entry_t *fe;
1196
1197 fe = panel_current_entry (the_other_panel);
1198 if (fe != NULL)
1199 file_name = fe->fname->str;
1200 }
1201
1202 mcview_load ((WView *) new_widget, 0, file_name, 0, 0, 0);
1203 break;
1204 }
1205
1206 default:
1207 break;
1208 }
1209
1210 if (type != view_listing)
1211
1212
1213 save_panel_dir (num);
1214
1215 panels[num].type = type;
1216 panels[num].widget = new_widget;
1217
1218
1219
1220 if (old_widget != NULL)
1221 {
1222 if (old_type == view_listing)
1223 {
1224
1225
1226 dlg_save_history (filemanager);
1227 }
1228
1229 widget_replace (old_widget, new_widget);
1230 }
1231
1232 if (type == view_listing)
1233 {
1234 WPanel *panel = PANEL (new_widget);
1235
1236
1237 if (old_widget != NULL)
1238 {
1239 ev_history_load_save_t event_data = { NULL, new_widget };
1240
1241 mc_event_raise (filemanager->event_group, MCEVENT_HISTORY_LOAD, &event_data);
1242 }
1243
1244 if (num == 0)
1245 left_panel = panel;
1246 else
1247 right_panel = panel;
1248
1249
1250 set_panel_formats (panel);
1251 }
1252
1253 if (type == view_tree)
1254 the_tree = (WTree *) new_widget;
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264 if ((type != view_listing) && (current_panel == PANEL (old_widget)))
1265 current_panel = num == 0 ? right_panel : left_panel;
1266
1267 g_free (old_widget);
1268 }
1269
1270
1271
1272
1273
1274
1275 void
1276 swap_panels (void)
1277 {
1278 WPanel *panel1, *panel2;
1279 Widget *tmp_widget;
1280
1281 panel1 = PANEL (panels[0].widget);
1282 panel2 = PANEL (panels[1].widget);
1283
1284 if (panels[0].type == view_listing && panels[1].type == view_listing
1285 && !mc_config_get_bool (mc_global.main_config, CONFIG_PANELS_SECTION, "simple_swap", FALSE))
1286 {
1287 WPanel panel;
1288
1289 #define panelswap(x) \
1290 panel.x = panel1->x; \
1291 panel1->x = panel2->x; \
1292 panel2->x = panel.x;
1293
1294 panelswap (dir);
1295 panelswap (active);
1296 panelswap (cwd_vpath);
1297 panelswap (lwd_vpath);
1298 panelswap (marked);
1299 panelswap (dirs_marked);
1300 panelswap (total);
1301 panelswap (top);
1302 panelswap (current);
1303 panelswap (is_panelized);
1304 panelswap (panelized_descr);
1305 panelswap (dir_stat);
1306 #undef panelswap
1307
1308 panel1->quick_search.active = FALSE;
1309 panel2->quick_search.active = FALSE;
1310
1311 if (current_panel == panel1)
1312 current_panel = panel2;
1313 else
1314 current_panel = panel1;
1315
1316
1317 if (memcmp (&panel1->sort_info, &panel2->sort_info, sizeof (dir_sort_options_t)) != 0)
1318 {
1319 panel_re_sort (other_panel);
1320 panel_re_sort (current_panel);
1321 }
1322
1323 if (widget_is_active (panels[0].widget))
1324 widget_select (panels[1].widget);
1325 else if (widget_is_active (panels[1].widget))
1326 widget_select (panels[0].widget);
1327 }
1328 else
1329 {
1330 WPanel *tmp_panel;
1331 WRect r;
1332 int tmp_type;
1333
1334 tmp_panel = right_panel;
1335 right_panel = left_panel;
1336 left_panel = tmp_panel;
1337
1338 if (panels[0].type == view_listing)
1339 {
1340 if (strcmp (panel1->name, get_nth_panel_name (0)) == 0)
1341 {
1342 g_free (panel1->name);
1343 panel1->name = g_strdup (get_nth_panel_name (1));
1344 }
1345 }
1346 if (panels[1].type == view_listing)
1347 {
1348 if (strcmp (panel2->name, get_nth_panel_name (1)) == 0)
1349 {
1350 g_free (panel2->name);
1351 panel2->name = g_strdup (get_nth_panel_name (0));
1352 }
1353 }
1354
1355 r = panels[0].widget->rect;
1356 panels[0].widget->rect = panels[1].widget->rect;
1357 panels[1].widget->rect = r;
1358
1359 tmp_widget = panels[0].widget;
1360 panels[0].widget = panels[1].widget;
1361 panels[1].widget = tmp_widget;
1362 tmp_type = panels[0].type;
1363 panels[0].type = panels[1].type;
1364 panels[1].type = tmp_type;
1365
1366
1367 if (panels[0].type == view_listing)
1368 set_panel_formats (PANEL (panels[0].widget));
1369 if (panels[1].type == view_listing)
1370 set_panel_formats (PANEL (panels[1].widget));
1371 }
1372 }
1373
1374
1375
1376 panel_view_mode_t
1377 get_panel_type (int idx)
1378 {
1379 return panels[idx].type;
1380 }
1381
1382
1383
1384 Widget *
1385 get_panel_widget (int idx)
1386 {
1387 return panels[idx].widget;
1388 }
1389
1390
1391
1392 int
1393 get_current_index (void)
1394 {
1395 return (panels[0].widget == WIDGET (current_panel) ? 0 : 1);
1396 }
1397
1398
1399
1400 int
1401 get_other_index (void)
1402 {
1403 return (get_current_index () == 0 ? 1 : 0);
1404 }
1405
1406
1407
1408 WPanel *
1409 get_other_panel (void)
1410 {
1411 return PANEL (get_panel_widget (get_other_index ()));
1412 }
1413
1414
1415
1416
1417 panel_view_mode_t
1418 get_current_type (void)
1419 {
1420 return (panels[0].widget == WIDGET (current_panel) ? panels[0].type : panels[1].type);
1421 }
1422
1423
1424
1425
1426 panel_view_mode_t
1427 get_other_type (void)
1428 {
1429 return (panels[0].widget == WIDGET (current_panel) ? panels[1].type : panels[0].type);
1430 }
1431
1432
1433
1434
1435 void
1436 save_panel_dir (int idx)
1437 {
1438 panel_view_mode_t type;
1439
1440 type = get_panel_type (idx);
1441 if (type == view_listing)
1442 {
1443 WPanel *p;
1444
1445 p = PANEL (get_panel_widget (idx));
1446 if (p != NULL)
1447 {
1448 g_free (panels[idx].last_saved_dir);
1449
1450 panels[idx].last_saved_dir = g_strdup (vfs_path_as_str (p->cwd_vpath));
1451 }
1452 }
1453 }
1454
1455
1456
1457
1458
1459 char *
1460 get_panel_dir_for (const WPanel *widget)
1461 {
1462 int i;
1463
1464 for (i = 0; i < MAX_VIEWS; i++)
1465 if (PANEL (get_panel_widget (i)) == widget)
1466 break;
1467
1468 if (i >= MAX_VIEWS)
1469 return g_strdup (".");
1470
1471 if (get_panel_type (i) == view_listing)
1472 {
1473 vfs_path_t *cwd_vpath;
1474
1475 cwd_vpath = PANEL (get_panel_widget (i))->cwd_vpath;
1476 return g_strdup (vfs_path_as_str (cwd_vpath));
1477 }
1478
1479 return g_strdup (panels[i].last_saved_dir);
1480 }
1481
1482
1483
1484 #ifdef ENABLE_SUBSHELL
1485 gboolean
1486 do_load_prompt (void)
1487 {
1488 gboolean ret = FALSE;
1489
1490 if (!read_subshell_prompt ())
1491 return ret;
1492
1493
1494 if (top_dlg != NULL && DIALOG (top_dlg->data) == filemanager && command_prompt)
1495 {
1496 setup_cmdline ();
1497
1498
1499
1500
1501
1502 widget_update_cursor (WIDGET (filemanager));
1503 mc_refresh ();
1504 ret = TRUE;
1505 }
1506 update_subshell_prompt = TRUE;
1507 return ret;
1508 }
1509
1510
1511
1512 int
1513 load_prompt (int fd, void *unused)
1514 {
1515 (void) fd;
1516 (void) unused;
1517
1518 if (should_read_new_subshell_prompt)
1519 do_load_prompt ();
1520 else
1521 flush_subshell (0, QUIETLY);
1522
1523 return 0;
1524 }
1525 #endif
1526
1527
1528
1529 void
1530 title_path_prepare (char **path, char **login)
1531 {
1532 char host[BUF_TINY];
1533 struct passwd *pw = NULL;
1534 int res = 0;
1535
1536 *path =
1537 vfs_path_to_str_flags (current_panel->cwd_vpath, 0, VPF_STRIP_HOME | VPF_STRIP_PASSWORD);
1538
1539 res = gethostname (host, sizeof (host));
1540 if (res != 0)
1541 host[0] = '\0';
1542 else
1543 host[sizeof (host) - 1] = '\0';
1544
1545 pw = getpwuid (getuid ());
1546 if (pw != NULL)
1547 *login = g_strdup_printf ("%s@%s", pw->pw_name, host);
1548 else
1549 *login = g_strdup (host);
1550 }
1551
1552
1553
1554
1555 void
1556 update_xterm_title_path (void)
1557 {
1558 if (mc_global.tty.xterm_flag && xterm_title)
1559 {
1560 char *p;
1561 char *path;
1562 char *login;
1563
1564 title_path_prepare (&path, &login);
1565
1566 p = g_strdup_printf ("mc [%s]:%s", login, path);
1567 g_free (login);
1568 g_free (path);
1569
1570 fprintf (stdout, ESC_STR "]0;%s" ESC_STR "\\", str_term_form (p));
1571 g_free (p);
1572
1573 if (!mc_global.tty.alternate_plus_minus)
1574 numeric_keypad_mode ();
1575 (void) fflush (stdout);
1576 }
1577 }
1578
1579
1580
1581
1582 void
1583 update_terminal_cwd (void)
1584 {
1585 if (mc_global.tty.xterm_flag && vfs_current_is_local ())
1586 {
1587 const gchar *host;
1588 char *path, *path_uri;
1589
1590 host = g_get_host_name ();
1591 path = vfs_path_to_str_flags (current_panel->cwd_vpath, 0, VPF_NONE);
1592 path_uri = g_uri_escape_string (path, "/", FALSE);
1593
1594 fprintf (stdout, ESC_STR "]7;file://%s%s" ESC_STR "\\", host, path_uri);
1595 (void) fflush (stdout);
1596
1597 g_free (path_uri);
1598 g_free (path);
1599 }
1600 }
1601
1602