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
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 {
987 g_free (mc_prompt);
988 mc_prompt = g_strndup (subshell_prompt->str, subshell_prompt->len);
989 }
990
991 (void) strip_ctrl_codes (mc_prompt);
992 }
993 #endif
994
995 prompt_width = str_term_width1 (mc_prompt);
996
997
998 if (r->cols > 8 && prompt_width > r->cols - 8)
999 {
1000 int prompt_len;
1001
1002 prompt_width = r->cols - 8;
1003 prompt_len = str_offset_to_pos (mc_prompt, prompt_width);
1004 mc_prompt[prompt_len] = '\0';
1005 }
1006
1007 y = r->lines - 1 - (mc_global.keybar_visible ? 1 : 0);
1008
1009 widget_set_size (WIDGET (the_prompt), y, r->x, 1, prompt_width);
1010 label_set_text (the_prompt, mc_prompt);
1011 widget_set_size (WIDGET (cmdline), y, r->x + prompt_width, 1, r->cols - prompt_width);
1012
1013 widget_show (WIDGET (the_prompt));
1014 widget_show (WIDGET (cmdline));
1015 }
1016
1017
1018
1019 void
1020 use_dash (gboolean flag)
1021 {
1022 if (flag)
1023 ok_to_refresh++;
1024 else
1025 ok_to_refresh--;
1026 }
1027
1028
1029
1030 void
1031 set_hintbar (const char *str)
1032 {
1033 label_set_text (the_hint, str);
1034 if (ok_to_refresh > 0)
1035 mc_refresh ();
1036 }
1037
1038
1039
1040 void
1041 rotate_dash (gboolean show)
1042 {
1043 static gint64 timestamp = 0;
1044
1045 static const gint64 delay = G_USEC_PER_SEC / 10;
1046
1047 const Widget *w = CONST_WIDGET (filemanager);
1048
1049 if (!nice_rotating_dash || (ok_to_refresh <= 0))
1050 return;
1051
1052 if (show && !mc_time_elapsed (×tamp, delay))
1053 return;
1054
1055 widget_gotoyx (w, menubar_visible ? 1 : 0, w->rect.cols - 1);
1056 tty_setcolor (NORMAL_COLOR);
1057
1058 if (!show)
1059 tty_print_alt_char (ACS_URCORNER, FALSE);
1060 else
1061 {
1062 static const char rotating_dash[4] MC_NONSTRING = "|/-\\";
1063 static size_t pos = 0;
1064
1065 tty_print_char (rotating_dash[pos]);
1066 pos = (pos + 1) % sizeof (rotating_dash);
1067 }
1068
1069 mc_refresh ();
1070 }
1071
1072
1073
1074 const char *
1075 get_nth_panel_name (int num)
1076 {
1077 if (num == 0)
1078 return "New Left Panel";
1079
1080 if (num == 1)
1081 return "New Right Panel";
1082
1083 {
1084 static char buffer[BUF_SMALL];
1085
1086 g_snprintf (buffer, sizeof (buffer), "%ith Panel", num);
1087 return buffer;
1088 }
1089 }
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104 void
1105 create_panel (int num, panel_view_mode_t type)
1106 {
1107 WRect r = { 0, 0, 0, 0 };
1108 unsigned int the_other = 0;
1109 Widget *new_widget = NULL, *old_widget = NULL;
1110 panel_view_mode_t old_type = view_listing;
1111
1112 if (num >= MAX_VIEWS)
1113 {
1114 fprintf (stderr, "Cannot allocate more that %d views\n", MAX_VIEWS);
1115 abort ();
1116 }
1117
1118 if (type != view_listing)
1119 {
1120 the_other = num == 0 ? 1 : 0;
1121
1122 if (panels[the_other].type != view_listing)
1123 return;
1124 }
1125
1126
1127 if (panels[num].widget != NULL)
1128 {
1129 Widget *w = panels[num].widget;
1130 WPanel *panel = PANEL (w);
1131
1132 r = w->rect;
1133 old_widget = w;
1134 old_type = panels[num].type;
1135
1136 if (old_type == view_listing && panel->frame_size == frame_full && type != view_listing)
1137 {
1138 int md_cols = CONST_WIDGET (filemanager)->rect.cols;
1139
1140 if (panels_layout.horizontal_split)
1141 {
1142 r.cols = md_cols;
1143 r.x = 0;
1144 }
1145 else
1146 {
1147 r.cols = md_cols - panels_layout.left_panel_size;
1148 if (num == 1)
1149 r.x = panels_layout.left_panel_size;
1150 }
1151 }
1152 }
1153
1154
1155
1156 if (old_widget == NULL && type != view_listing)
1157 panels[num].last_saved_dir = vfs_get_cwd ();
1158
1159 switch (type)
1160 {
1161 case view_nothing:
1162 case view_listing:
1163 {
1164 gboolean last_was_panel;
1165
1166 last_was_panel = old_widget != NULL && get_panel_type (num) != view_listing;
1167 new_widget = restore_into_right_dir_panel (num, last_was_panel, &r);
1168 break;
1169 }
1170
1171 case view_info:
1172 new_widget = WIDGET (info_new (&r));
1173 break;
1174
1175 case view_tree:
1176 new_widget = WIDGET (tree_new (&r, TRUE));
1177 break;
1178
1179 case view_quick:
1180 {
1181 WPanel *the_other_panel;
1182 const char *file_name = "";
1183
1184 new_widget = WIDGET (mcview_new (&r, TRUE));
1185 the_other_panel = PANEL (panels[the_other].widget);
1186 if (the_other_panel != NULL)
1187 {
1188 const file_entry_t *fe;
1189
1190 fe = panel_current_entry (the_other_panel);
1191 if (fe != NULL)
1192 file_name = fe->fname->str;
1193 }
1194
1195 mcview_load ((WView *) new_widget, 0, file_name, 0, 0, 0);
1196 break;
1197 }
1198
1199 default:
1200 break;
1201 }
1202
1203 if (type != view_listing)
1204
1205
1206 save_panel_dir (num);
1207
1208 panels[num].type = type;
1209 panels[num].widget = new_widget;
1210
1211
1212
1213 if (old_widget != NULL)
1214 {
1215 if (old_type == view_listing)
1216 {
1217
1218
1219 dlg_save_history (filemanager);
1220 }
1221
1222 widget_replace (old_widget, new_widget);
1223 }
1224
1225 if (type == view_listing)
1226 {
1227 WPanel *panel = PANEL (new_widget);
1228
1229
1230 if (old_widget != NULL)
1231 {
1232 ev_history_load_save_t event_data = { NULL, new_widget };
1233
1234 mc_event_raise (filemanager->event_group, MCEVENT_HISTORY_LOAD, &event_data);
1235 }
1236
1237 if (num == 0)
1238 left_panel = panel;
1239 else
1240 right_panel = panel;
1241
1242
1243 set_panel_formats (panel);
1244 }
1245
1246 if (type == view_tree)
1247 the_tree = (WTree *) new_widget;
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257 if ((type != view_listing) && (current_panel == PANEL (old_widget)))
1258 current_panel = num == 0 ? right_panel : left_panel;
1259
1260 g_free (old_widget);
1261 }
1262
1263
1264
1265
1266
1267
1268 void
1269 swap_panels (void)
1270 {
1271 WPanel *panel1, *panel2;
1272 Widget *tmp_widget;
1273
1274 panel1 = PANEL (panels[0].widget);
1275 panel2 = PANEL (panels[1].widget);
1276
1277 if (panels[0].type == view_listing && panels[1].type == view_listing
1278 && !mc_config_get_bool (mc_global.main_config, CONFIG_PANELS_SECTION, "simple_swap", FALSE))
1279 {
1280 WPanel panel;
1281
1282 #define panelswap(x) \
1283 panel.x = panel1->x; \
1284 panel1->x = panel2->x; \
1285 panel2->x = panel.x;
1286
1287 panelswap (dir);
1288 panelswap (active);
1289 panelswap (cwd_vpath);
1290 panelswap (lwd_vpath);
1291 panelswap (marked);
1292 panelswap (dirs_marked);
1293 panelswap (total);
1294 panelswap (top);
1295 panelswap (current);
1296 panelswap (is_panelized);
1297 panelswap (panelized_descr);
1298 panelswap (dir_stat);
1299 #undef panelswap
1300
1301 panel1->quick_search.active = FALSE;
1302 panel2->quick_search.active = FALSE;
1303
1304 if (current_panel == panel1)
1305 current_panel = panel2;
1306 else
1307 current_panel = panel1;
1308
1309
1310 if (memcmp (&panel1->sort_info, &panel2->sort_info, sizeof (dir_sort_options_t)) != 0)
1311 {
1312 panel_re_sort (other_panel);
1313 panel_re_sort (current_panel);
1314 }
1315
1316 if (widget_is_active (panels[0].widget))
1317 widget_select (panels[1].widget);
1318 else if (widget_is_active (panels[1].widget))
1319 widget_select (panels[0].widget);
1320 }
1321 else
1322 {
1323 WPanel *tmp_panel;
1324 WRect r;
1325 int tmp_type;
1326
1327 tmp_panel = right_panel;
1328 right_panel = left_panel;
1329 left_panel = tmp_panel;
1330
1331 if (panels[0].type == view_listing)
1332 {
1333 if (strcmp (panel1->name, get_nth_panel_name (0)) == 0)
1334 {
1335 g_free (panel1->name);
1336 panel1->name = g_strdup (get_nth_panel_name (1));
1337 }
1338 }
1339 if (panels[1].type == view_listing)
1340 {
1341 if (strcmp (panel2->name, get_nth_panel_name (1)) == 0)
1342 {
1343 g_free (panel2->name);
1344 panel2->name = g_strdup (get_nth_panel_name (0));
1345 }
1346 }
1347
1348 r = panels[0].widget->rect;
1349 panels[0].widget->rect = panels[1].widget->rect;
1350 panels[1].widget->rect = r;
1351
1352 tmp_widget = panels[0].widget;
1353 panels[0].widget = panels[1].widget;
1354 panels[1].widget = tmp_widget;
1355 tmp_type = panels[0].type;
1356 panels[0].type = panels[1].type;
1357 panels[1].type = tmp_type;
1358
1359
1360 if (panels[0].type == view_listing)
1361 set_panel_formats (PANEL (panels[0].widget));
1362 if (panels[1].type == view_listing)
1363 set_panel_formats (PANEL (panels[1].widget));
1364 }
1365 }
1366
1367
1368
1369 panel_view_mode_t
1370 get_panel_type (int idx)
1371 {
1372 return panels[idx].type;
1373 }
1374
1375
1376
1377 Widget *
1378 get_panel_widget (int idx)
1379 {
1380 return panels[idx].widget;
1381 }
1382
1383
1384
1385 int
1386 get_current_index (void)
1387 {
1388 return (panels[0].widget == WIDGET (current_panel) ? 0 : 1);
1389 }
1390
1391
1392
1393 int
1394 get_other_index (void)
1395 {
1396 return (get_current_index () == 0 ? 1 : 0);
1397 }
1398
1399
1400
1401 WPanel *
1402 get_other_panel (void)
1403 {
1404 return PANEL (get_panel_widget (get_other_index ()));
1405 }
1406
1407
1408
1409
1410 panel_view_mode_t
1411 get_current_type (void)
1412 {
1413 return (panels[0].widget == WIDGET (current_panel) ? panels[0].type : panels[1].type);
1414 }
1415
1416
1417
1418
1419 panel_view_mode_t
1420 get_other_type (void)
1421 {
1422 return (panels[0].widget == WIDGET (current_panel) ? panels[1].type : panels[0].type);
1423 }
1424
1425
1426
1427
1428 void
1429 save_panel_dir (int idx)
1430 {
1431 panel_view_mode_t type;
1432
1433 type = get_panel_type (idx);
1434 if (type == view_listing)
1435 {
1436 WPanel *p;
1437
1438 p = PANEL (get_panel_widget (idx));
1439 if (p != NULL)
1440 {
1441 g_free (panels[idx].last_saved_dir);
1442
1443 panels[idx].last_saved_dir = g_strdup (vfs_path_as_str (p->cwd_vpath));
1444 }
1445 }
1446 }
1447
1448
1449
1450
1451
1452 char *
1453 get_panel_dir_for (const WPanel *widget)
1454 {
1455 int i;
1456
1457 for (i = 0; i < MAX_VIEWS; i++)
1458 if (PANEL (get_panel_widget (i)) == widget)
1459 break;
1460
1461 if (i >= MAX_VIEWS)
1462 return g_strdup (".");
1463
1464 if (get_panel_type (i) == view_listing)
1465 {
1466 vfs_path_t *cwd_vpath;
1467
1468 cwd_vpath = PANEL (get_panel_widget (i))->cwd_vpath;
1469 return g_strdup (vfs_path_as_str (cwd_vpath));
1470 }
1471
1472 return g_strdup (panels[i].last_saved_dir);
1473 }
1474
1475
1476
1477 #ifdef ENABLE_SUBSHELL
1478 gboolean
1479 do_load_prompt (void)
1480 {
1481 gboolean ret = FALSE;
1482
1483 if (!read_subshell_prompt ())
1484 return ret;
1485
1486
1487 if (top_dlg != NULL && DIALOG (top_dlg->data) == filemanager && command_prompt)
1488 {
1489 setup_cmdline ();
1490
1491
1492
1493
1494
1495 widget_update_cursor (WIDGET (filemanager));
1496 mc_refresh ();
1497 ret = TRUE;
1498 }
1499 update_subshell_prompt = TRUE;
1500 return ret;
1501 }
1502
1503
1504
1505 int
1506 load_prompt (int fd, void *unused)
1507 {
1508 (void) fd;
1509 (void) unused;
1510
1511 if (should_read_new_subshell_prompt)
1512 do_load_prompt ();
1513 else
1514 flush_subshell (0, QUIETLY);
1515
1516 return 0;
1517 }
1518 #endif
1519
1520
1521
1522 void
1523 title_path_prepare (char **path, char **login)
1524 {
1525 char host[BUF_TINY];
1526 struct passwd *pw = NULL;
1527 int res = 0;
1528
1529 *path =
1530 vfs_path_to_str_flags (current_panel->cwd_vpath, 0, VPF_STRIP_HOME | VPF_STRIP_PASSWORD);
1531
1532 res = gethostname (host, sizeof (host));
1533 if (res != 0)
1534 host[0] = '\0';
1535 else
1536 host[sizeof (host) - 1] = '\0';
1537
1538 pw = getpwuid (getuid ());
1539 if (pw != NULL)
1540 *login = g_strdup_printf ("%s@%s", pw->pw_name, host);
1541 else
1542 *login = g_strdup (host);
1543 }
1544
1545
1546
1547
1548 void
1549 update_xterm_title_path (void)
1550 {
1551 if (mc_global.tty.xterm_flag && xterm_title)
1552 {
1553 char *p;
1554 char *path;
1555 char *login;
1556
1557 title_path_prepare (&path, &login);
1558
1559 p = g_strdup_printf ("mc [%s]:%s", login, path);
1560 g_free (login);
1561 g_free (path);
1562
1563 fprintf (stdout, ESC_STR "]0;%s" ESC_STR "\\", str_term_form (p));
1564 g_free (p);
1565
1566 if (!mc_global.tty.alternate_plus_minus)
1567 numeric_keypad_mode ();
1568 (void) fflush (stdout);
1569 }
1570 }
1571
1572
1573
1574
1575 void
1576 update_terminal_cwd (void)
1577 {
1578 if (mc_global.tty.xterm_flag && vfs_current_is_local ())
1579 {
1580 const gchar *host;
1581 char *path, *path_uri;
1582
1583 host = g_get_host_name ();
1584 path = vfs_path_to_str_flags (current_panel->cwd_vpath, 0, VPF_NONE);
1585 path_uri = g_uri_escape_string (path, "/", FALSE);
1586
1587 fprintf (stdout, ESC_STR "]7;file://%s%s" ESC_STR "\\", host, path_uri);
1588 (void) fflush (stdout);
1589
1590 g_free (path_uri);
1591 g_free (path);
1592 }
1593 }
1594
1595