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