📄 layout.c
字号:
/* Panel layout module for the Midnight Commander
Copyright (C) 1995 the Free Software Foundation
Written: 1995 Janne Kukonlehto
1995 Miguel de Icaza
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <config.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <sys/param.h> /* Required by tree.h */
#include <sys/types.h>
#include <sys/stat.h>
#if (!defined(__IBMC__) && !defined(__IBMCPP__)) && !defined(OS2_NT)
# include <termios.h>
/*
* If TIOCGWINSZ supported, make it available here, because window-
* resizing code depends on it...
*/
# ifdef __QNX__ /* Maybe not only QNX-specific... */
# include <sys/ioctl.h>
# endif
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include <signal.h>
#include "tty.h"
#include "mad.h"
#include "util.h" /* Needed for the externs */
#include "win.h"
#include "color.h"
#include "key.h"
#include "dlg.h"
#include "widget.h"
#include "command.h"
#include "dialog.h" /* For do_refresh() */
#include "profile.h" /* For sync_profiles() */
#include "mouse.h"
#define WANT_WIDGETS
#include "main.h"
#include "subshell.h" /* For use_subshell and resize_subshell() */
#include "tree.h"
#include "menu.h"
/* Needed for the extern declarations of integer parameters */
#include "dir.h"
#include "panel.h" /* The Panel widget */
#include "file.h"
#include "cons.saver.h"
#include "layout.h"
#include "info.h" /* The Info widget */
#include "view.h" /* The view widget */
#define WANT_DEFAULTS
#include "setup.h" /* For save_setup() */
#include "x.h"
/* "$Id: layout.c 15091 2005-05-07 21:24:31Z sedwards $" */
/* Controls the display of the rotating dash on the verbose mode */
int nice_rotating_dash = 1;
/* If set, then we have to call the layout_change routine from main */
int layout_do_change = 0;
/* Set if the panels are split horizontally */
int horizontal_split = 0;
/* Set if the window has changed it's size */
int winch_flag = 0;
/* Set if the split is the same */
int equal_split = 1;
/* First panel size if the panel are not split equally */
int first_panel_size = 0;
/* The number of output lines shown (if available) */
int output_lines = 0;
/* Set if the command prompt is to be displayed */
int command_prompt = 1;
/* Set if the nice and usefull keybar is visible */
int keybar_visible = 1;
/* Set if the nice message (hint) bar is visible */
int message_visible = 1;
/* Set if you want the message bar shown in xterm title bar to save space */
int xterm_hintbar = 0;
/* The starting line for the output of the subprogram */
int output_start_y = 0;
/* The maximum number of views managed by the set_display_type routine */
/* Must be at least two (for current and other). Please note that until */
/* Janne gets around this, we will only manage two of them :-) */
#define MAX_VIEWS 2
struct {
int type;
Widget *widget;
} panels [MAX_VIEWS];
/* These variables are used to avoid updating the information unless */
/* we need it */
static int old_first_panel_size;
static int old_horizontal_split;
static int old_output_lines;
/* Internal variables */
static int _horizontal_split;
static int _equal_split;
static int _first_panel_size;
static int _menubar_visible;
static int _output_lines;
static int _command_prompt;
static int _keybar_visible;
static int _message_visible;
static int _xterm_hintbar;
static int _permission_mode;
static int _filetype_mode;
static int height;
#define MINWIDTH 10
#define MINHEIGHT 5
#define BY 12
#define B_2LEFT B_USER
#define B_2RIGHT B_USER + 1
#define B_PLUS B_USER + 2
#define B_MINUS B_USER + 3
static Dlg_head *layout_dlg;
static char *s_split_direction [2] = {
N_("&Vertical"),
N_("&Horizontal")
};
WRadio *radio_widget;
static struct {
char *text;
int *variable;
WCheck *widget;
char *tkname;
} check_options [] = {
{ N_("&Xterm hintbar"), &xterm_hintbar, 0, "h" },
{ N_("h&Intbar visible"), &message_visible, 0, "v" },
{ N_("&Keybar visible"), &keybar_visible, 0, "k" },
{ N_("command &Prompt"), &command_prompt, 0, "p" },
{ N_("show &Mini status"), &show_mini_info, 0, "m" },
{ N_("menu&Bar visible"), &menubar_visible, 0, "me" },
{ N_("&Equal split"), &equal_split, 0, "eq" },
{ N_("pe&Rmissions"), &permission_mode, 0, "pr" },
{ N_("&File types"), &filetype_mode, 0, "ft" },
{ 0, 0, 0, 0 }
};
static int first_width, second_width;
static char *layout_title, *title1, *title2, *title3, *output_lines_label;
static WButton *bleft_widget, *bright_widget;
static void _check_split (void)
{
if (_horizontal_split){
if (_equal_split)
_first_panel_size = height / 2;
else if (_first_panel_size < MINHEIGHT)
_first_panel_size = MINHEIGHT;
else if (_first_panel_size > height - MINHEIGHT)
_first_panel_size = height - MINHEIGHT;
} else {
if (_equal_split)
_first_panel_size = COLS / 2;
else if (_first_panel_size < MINWIDTH)
_first_panel_size = MINWIDTH;
else if (_first_panel_size > COLS - MINWIDTH)
_first_panel_size = COLS - MINWIDTH;
}
}
static void update_split (void)
{
/* Check split has to be done before testing if it changed, since
it can change due to calling _check_split() as well*/
_check_split ();
/* To avoid setting the cursor to the wrong place */
if ((old_first_panel_size == _first_panel_size) &&
(old_horizontal_split == _horizontal_split)){
return;
}
old_first_panel_size = _first_panel_size;
old_horizontal_split = _horizontal_split;
attrset (COLOR_NORMAL);
dlg_move (layout_dlg, 6, 6);
printw ("%03d", _first_panel_size);
dlg_move (layout_dlg, 6, 18);
if (_horizontal_split)
printw ("%03d", height - _first_panel_size);
else
printw ("%03d", COLS - _first_panel_size);
}
static int b2left_cback (int action, void *data)
{
if (_equal_split){
/* Turn equal split off */
_equal_split = 0;
check_options [6].widget->state = check_options [6].widget->state & ~C_BOOL;
dlg_select_widget (layout_dlg, check_options [6].widget);
dlg_select_widget (layout_dlg, bleft_widget);
}
_first_panel_size++;
return 0;
}
static int b2right_cback (int action, void *data)
{
if (_equal_split){
/* Turn equal split off */
_equal_split = 0;
check_options [6].widget->state = check_options [6].widget->state & ~C_BOOL;
dlg_select_widget (layout_dlg, check_options [6].widget);
dlg_select_widget (layout_dlg, bright_widget);
}
_first_panel_size--;
return 0;
}
static int bplus_cback (int action, void *data)
{
if (_output_lines < 99)
_output_lines++;
return 0;
}
static int bminus_cback (int action, void *data)
{
if (_output_lines > 0)
_output_lines--;
return 0;
}
static int layout_callback (struct Dlg_head *h, int Id, int Msg)
{
switch (Msg){
case DLG_DRAW:
#ifndef HAVE_X
/*When repainting the whole dialog (e.g. with C-l) we have to
update everything*/
old_first_panel_size = -1;
old_horizontal_split = -1;
old_output_lines = -1;
attrset (COLOR_NORMAL);
dlg_erase (h);
draw_box (h, 1, 2, h->lines - 2, h->cols - 4);
draw_box (h, 2, 4, 6, first_width);
draw_box (h, 8, 4, 4, first_width);
draw_box (h, 2, 5 + first_width, 10, second_width);
attrset (COLOR_HOT_NORMAL);
dlg_move (h, 1, (h->cols - strlen(layout_title))/2);
addstr (layout_title);
dlg_move (h, 2, 5);
addstr (title1);
dlg_move (h, 8, 5);
addstr (title2);
dlg_move (h, 2, 6 + first_width);
addstr (title3);
update_split ();
dlg_move (h, 6, 13);
addch ('=');
if (console_flag){
if (old_output_lines != _output_lines){
old_output_lines = _output_lines;
attrset (COLOR_NORMAL);
dlg_move (h, 9, 16 + first_width);
addstr (output_lines_label);
dlg_move (h, 9, 10 + first_width);
printw ("%02d", _output_lines);
}
}
#endif
break;
case DLG_POST_KEY:
_filetype_mode = check_options [8].widget->state & C_BOOL;
_permission_mode = check_options [7].widget->state & C_BOOL;
#ifndef HAVE_X
_equal_split = check_options [6].widget->state & C_BOOL;
#endif
_menubar_visible = check_options [5].widget->state & C_BOOL;
_command_prompt = check_options [4].widget->state & C_BOOL;
_keybar_visible = check_options [2].widget->state & C_BOOL;
_message_visible = check_options [1].widget->state & C_BOOL;
_xterm_hintbar = check_options [0].widget->state & C_BOOL;
if (console_flag){
int minimum;
if (_output_lines < 0)
_output_lines = 0;
height = LINES - _keybar_visible - _command_prompt -
_menubar_visible - _output_lines - _message_visible;
if (_message_visible && _xterm_hintbar && xterm_flag) height++;
minimum = MINHEIGHT * (1 + _horizontal_split);
if (height < minimum){
_output_lines -= minimum - height;
height = minimum;
}
} else {
height = LINES - _keybar_visible - _command_prompt -
_menubar_visible - _output_lines - _message_visible;
if (_message_visible && _xterm_hintbar && xterm_flag) height++;
}
if (_horizontal_split != radio_widget->sel){
_horizontal_split = radio_widget->sel;
if (_horizontal_split)
_first_panel_size = height / 2;
else
_first_panel_size = COLS / 2;
}
update_split ();
if (console_flag){
if (old_output_lines != _output_lines){
old_output_lines = _output_lines;
attrset (COLOR_NORMAL);
dlg_move (h, 9, 10 + first_width);
printw ("%02d", _output_lines);
}
}
break;
case DLG_END:
break;
}
return 0;
}
static void init_layout (void)
{
static int i18n_layt_flag = 0;
static int b1, b2, b3;
int i = sizeof (s_split_direction) / sizeof(char*) ;
char* ok_button = _("&Ok");
char* cancel_button = _("&Cancel");
char* save_button = _("&Save");
if (!i18n_layt_flag)
{
register int l1;
first_width = 19; /* length of line with '<' '>' buttons */
layout_title = _(" Layout ");
title1 = _(" Panel split ");
title2 = _(" Highlight... ");
title3 = _(" Other options ");
output_lines_label = _("output lines");
while (i--)
{
s_split_direction [i] = _(s_split_direction [i]);
l1 = strlen (s_split_direction [i]) + 7;
if (l1 > first_width)
first_width = l1;
}
for (i = 0; i <= 8; i++)
{
check_options[i].text = _(check_options[i].text);
l1 = strlen (check_options[i].text) + 7;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -