📄 view.c
字号:
else if (c == KEY_RIGHT)
move_right (view);
else return 0;
return 1;
}
void
set_monitor (WView *view, int set_on)
{
int old = view->monitor;
view->monitor = set_on;
if (view->monitor){
move_to_bottom (view);
view->bottom_first = -1;
set_idle_proc (view->widget.parent, 1);
} else {
if (old)
set_idle_proc (view->widget.parent, 0);
}
}
void
continue_search (WView *view)
{
if (view->last_search){
(*view->last_search)(view, view->search_exp);
} else {
/* if not... then ask for an expression */
normal_search (view, 1);
}
}
/* Both views */
static int
view_handle_key (WView *view, int c)
{
int prev_monitor = view->monitor;
set_monitor (view, off);
if (view->hex_mode) {
switch (c) {
case 0x09: /* Tab key */
view->view_side = 1 - view->view_side;
view->dirty++;
return 1;
case XCTRL('a'): /* Beginning of line */
view->edit_cursor -= view->edit_cursor % view->bytes_per_line;
view->dirty++;
return 1;
case XCTRL('b'): /* Character back */
move_left(view);
return 1;
case XCTRL('e'): /* End of line */
view->edit_cursor -= view->edit_cursor % view->bytes_per_line;
view->edit_cursor += view->bytes_per_line - 1;
view->dirty++;
return 1;
case XCTRL('f'): /* Character forward */
move_right(view);
return 1;
}
/* Trap 0-9,A-F,a-f for left side data entry (hex editing) */
if (view->view_side == view_side_left){
if ((c >= '0' && c <= '9') ||
(c >= 'A' && c <= 'F') ||
(c >= 'a' && c <= 'f')){
put_editkey (view, c);
return 1;
}
}
/* Trap all printable characters for right side data entry */
/* Also enter the value of the Enter key */
if (view->view_side == view_side_right){
if (c < 256 && (is_printable (c) || (c == '\n'))){
put_editkey(view, c);
return 1;
}
}
}
if (check_left_right_keys (view, c))
return 1;
if (check_movement_keys (c, 1, vheight, view, (movefn) view_move_backward, (movefn) view_move_forward,
(movefn) move_to_top, (movefn) move_to_bottom)){
return 1;
}
switch (c){
case '?':
regexp_search (view, -1);
return 1;
case '/':
regexp_search (view, 1);
return 1;
/* Continue search */
case XCTRL('s'):
case 'n':
case KEY_F(17):
continue_search (view);
return 1;
case XCTRL('r'):
if (view->last_search){
(*view->last_search)(view, view->search_exp);
} else {
normal_search (view, -1);
}
return 1;
/* toggle ruler */
case ALT('r'):
switch (ruler){
case 0:
ruler = 1; break;
case 1:
ruler = 2; break;
default:
ruler = 0; break;
}
view->dirty++;
return 1;
case 'h':
move_left (view);
return 1;
case 'j':
case '\n':
case 'e':
view_move_forward (view, 1);
return 1;
case 'd':
view_move_forward (view, vheight / 2);
return 1;
case 'u':
view_move_backward (view, vheight / 2);
return 1;
case 'k':
case 'y':
view_move_backward (view, 1);
return 1;
case 'l':
move_right (view);
return 1;
case ' ':
case 'f':
view_move_forward (view, vheight - 1);
return 1;
case '!':
exec_shell ();
return 1;
case 'F':
set_monitor (view, on);
return 1;
case 'b':
view_move_backward (view, vheight - 1);
return 1;
case KEY_IC:
view_move_backward (view, 2);
return 1;
case KEY_DC:
view_move_forward (view, 2);
return 1;
case 'm':
view->marks [view->marker] = view->start_display;
return 1;
case 'r':
view->start_display = view->marks [view->marker];
view->dirty++;
return 1;
/* Use to indicate parent that we want to see the next/previous file */
/* Only works on full screen mode */
case XCTRL('f'):
case XCTRL('b'):
if (!view->have_frame)
view->move_dir = c == XCTRL('f') ? 1 : -1;
/* fall */
case 'q':
case XCTRL('g'):
case ESC_CHAR:
if (view_ok_to_quit (view))
view->view_quit = 1;
return 1;
}
if (c >= '0' && c <= '9')
view->marker = c - '0';
/* Restore the monitor status */
set_monitor (view, prev_monitor);
/* Key not used */
return 0;
}
/* Both views */
int
view_event (WView *view, Gpm_Event *event, int *result)
{
*result = MOU_NORMAL;
if (event->type & (GPM_DOWN|GPM_DRAG)){
if (!view->wrap_mode){
if (event->x < view->widget.cols / 4){
move_left (view);
*result = MOU_REPEAT;
return 1;
}
if (event->x > 3 * vwidth / 4){
move_right (view);
*result = MOU_REPEAT;
return 1;
}
}
if (event->y < view->widget.lines / 3){
if (mouse_move_pages_viewer)
view_move_backward (view, view->widget.lines / 2 - 1);
else
view_move_backward (view, 1);
*result = MOU_REPEAT;
return 1;
}
else if (event->y > 2 * vheight /3){
if (mouse_move_pages_viewer)
view_move_forward (view, vheight / 2 - 1);
else
view_move_forward (view, 1);
*result = MOU_REPEAT;
return 1;
}
}
return 0;
}
/* Real view only */
int
real_view_event (Gpm_Event *event, void *x)
{
int result;
if (view_event ((WView *) x, event, &result))
view_update ((WView *) x);
return result;
}
/* }}} */
/* {{{ Window creation, destruction and a driver stub for real view */
static int
view_mode_callback (struct Dlg_head *h, int id, int msg)
{
return default_dlg_callback (h, id, msg);
}
#ifdef HAVE_XVIEW
/* Real view only */
void
view_adjust_size (Dlg_head *unused)
{
}
int
view (char *_command, char *_file, int *move_dir_p, int start_line)
{
int midnight_colors [4];
int error;
WView *wview;
wview = view_new (0, 0, COLS, LINES - 1, 0);
error = view_init (wview, _command, _file, start_line);
if (!error){
x_view (wview);
}
*move_dir_p = 0;
return !error;
}
#endif
#ifndef PORT_WANTS_VIEW
void
view_adjust_size (Dlg_head *h)
{
WView *view;
WButtonBar *bar;
/* Look up the viewer and the buttonbar, we assume only two widgets here */
view = (WView *) find_widget_type (h, (callback_fn) view_callback);
bar = (WButtonBar *) view->widget.parent->current->next->widget;
widget_set_size (&view->widget, 0, 0, LINES-1, COLS);
widget_set_size (&bar->widget, LINES-1, 0, 1, COLS);
}
/* Only the text mode edition uses this */
Dlg_head *view_dlg;
/* Real view only */
int
view (char *_command, char *_file, int *move_dir_p, int start_line)
{
int midnight_colors [4];
int error;
WView *wview;
WButtonBar *bar;
Dlg_head *our_dlg;
/* Create dialog and widgets, put them on the dialog */
our_dlg = create_dlg (0, 0, LINES, COLS, midnight_colors,
view_mode_callback, "[Internal File Viewer]",
"view",
DLG_NONE);
#ifndef HAVE_X
view_dlg = our_dlg;
#endif
wview = view_new (0, 0, COLS, LINES-1, 0);
bar = buttonbar_new (1);
add_widget (our_dlg, wview);
add_widget (our_dlg, bar);
error = view_init (wview, _command, _file, start_line);
if (move_dir_p)
*move_dir_p = 0;
/* Please note that if you add another widget,
* you have to modify view_adjust_size to
* be aware of it
*/
if (!error){
run_dlg (our_dlg);
if (move_dir_p)
*move_dir_p = wview->move_dir;
}
destroy_dlg (our_dlg);
return !error;
}
#endif
static void
view_hook (void *v)
{
WView *view = (WView *) v;
WPanel *panel;
struct stat s;
/* If the user is busy typing, wait until he finishes to update the
screen */
if (!is_idle ()){
if (!hook_present (idle_hook, view_hook))
add_hook (&idle_hook, view_hook, v);
return;
}
delete_hook (&idle_hook, view_hook);
if (get_current_type () == view_listing)
panel = cpanel;
else if (get_other_type () == view_listing)
panel = other_panel;
else
return;
if (S_ISLNK (panel->dir.list [panel->selected].buf.st_mode)){
if (mc_stat (panel->dir.list [panel->selected].fname, &s) != 0)
return;
if (!S_ISREG (s.st_mode))
return;
} else {
if (!S_ISREG (panel->dir.list [panel->selected].buf.st_mode))
return;
}
view_init (view, 0, panel->dir.list [panel->selected].fname, 0);
display (view);
view_status (view);
}
static int
view_callback (Dlg_head *h, WView *v, int msg, int par)
{
WView *view = (WView *) v;
int i;
switch (msg){
case WIDGET_INIT:
x_create_viewer (view);
if (view->have_frame)
add_hook (&select_file_hook, view_hook, view);
else
view_labels (view);
break;
case WIDGET_DRAW:
display (view);
view_status (view);
break;
case WIDGET_CURSOR:
if (view->hex_mode)
view_place_cursor (view);
break;
case WIDGET_KEY:
i = view_handle_key ((WView *)view, par);
if (view->view_quit)
dlg_stop (h);
else {
view_update (view);
}
return i;
case WIDGET_IDLE:
/* This event is generated when the user is using the 'F' flag */
view->bottom_first = -1;
move_to_bottom (view);
display (view);
view_status (view);
sleep (1);
return 1;
case WIDGET_FOCUS:
x_focus_view (view);
view_labels (view);
return 1;
}
return default_proc (h, msg, par);
}
WView *
view_new (int y, int x, int cols, int lines, int is_panel)
{
WView *view = xmalloc (sizeof (WView), "view_new");
init_widget (&view->widget, y, x, lines, cols,
(callback_fn) view_callback,
(destroy_fn) view_destroy,
(mouse_h) real_view_event, NULL);
view->filename = 0;
view->view_active = 0;
view->bottom_first = 0;
view->start_col = 0;
view->dirty = 0;
view->hex_mode = default_hex_mode;
view->hexedit_mode = default_hexedit_mode;
view->viewer_magic_flag = default_magic_flag;
view->viewer_nroff_flag = default_nroff_flag;
view->view_quit = 0;
view->move_dir = 0;
view->have_frame = is_panel;
view->last_byte = -1;
view->monitor = 0;
view->wrap_mode = global_wrap_mode;
x_init_view (view);
widget_want_cursor (view->widget, 0);
return view;
}
/* }}} */
/* {{{ Emacs local variables */
/*
Cause emacs to enter folding mode for this file:
Local variables:
end:
*/
/* }}} */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -