📄 textbox.c
字号:
wmove (dialog, cur_y, cur_x);
wrefresh (dialog);
break;
case '0': /* Beginning of line */
case 'H': /* Scroll left */
case 'h':
case KEY_LEFT:
if (hscroll <= 0)
break;
if (key == '0')
hscroll = 0;
else
hscroll--;
/* Reprint current page to scroll horizontally */
back_lines (page_length);
print_page (text, height - 4, width - 2);
wmove (dialog, cur_y, cur_x);
wrefresh (dialog);
break;
case 'L': /* Scroll right */
case 'l':
case KEY_RIGHT:
if (hscroll >= MAX_LEN)
break;
hscroll++;
/* Reprint current page to scroll horizontally */
back_lines (page_length);
print_page (text, height - 4, width - 2);
wmove (dialog, cur_y, cur_x);
wrefresh (dialog);
break;
case ESC:
break;
}
}
delwin (dialog);
free (buf);
close (fd);
return 1; /* ESC pressed */
}
/*
* Go back 'n' lines in text file. Called by dialog_textbox().
* 'page' will be updated to point to the desired line in 'buf'.
*/
static void
back_lines (int n)
{
int i, fpos;
begin_reached = 0;
/* We have to distinguish between end_reached and !end_reached
since at end of file, the line is not ended by a '\n'.
The code inside 'if' basically does a '--page' to move one
character backward so as to skip '\n' of the previous line */
if (!end_reached) {
/* Either beginning of buffer or beginning of file reached? */
if (page == buf) {
if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
endwin ();
fprintf (stderr, "\nError moving file pointer in "
"back_lines().\n");
exit (-1);
}
if (fpos > bytes_read) { /* Not beginning of file yet */
/* We've reached beginning of buffer, but not beginning of
file yet, so read previous part of file into buffer.
Note that we only move backward for BUF_SIZE/2 bytes,
but not BUF_SIZE bytes to avoid re-reading again in
print_page() later */
/* Really possible to move backward BUF_SIZE/2 bytes? */
if (fpos < BUF_SIZE / 2 + bytes_read) {
/* No, move less then */
if (lseek (fd, 0, SEEK_SET) == -1) {
endwin ();
fprintf (stderr, "\nError moving file pointer in "
"back_lines().\n");
exit (-1);
}
page = buf + fpos - bytes_read;
} else { /* Move backward BUF_SIZE/2 bytes */
if (lseek (fd, -(BUF_SIZE / 2 + bytes_read), SEEK_CUR)
== -1) {
endwin ();
fprintf (stderr, "\nError moving file pointer "
"in back_lines().\n");
exit (-1);
}
page = buf + BUF_SIZE / 2;
}
if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
endwin ();
fprintf (stderr, "\nError reading file in back_lines().\n");
exit (-1);
}
buf[bytes_read] = '\0';
} else { /* Beginning of file reached */
begin_reached = 1;
return;
}
}
if (*(--page) != '\n') { /* '--page' here */
/* Something's wrong... */
endwin ();
fprintf (stderr, "\nInternal error in back_lines().\n");
exit (-1);
}
}
/* Go back 'n' lines */
for (i = 0; i < n; i++)
do {
if (page == buf) {
if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
endwin ();
fprintf (stderr,
"\nError moving file pointer in back_lines().\n");
exit (-1);
}
if (fpos > bytes_read) {
/* Really possible to move backward BUF_SIZE/2 bytes? */
if (fpos < BUF_SIZE / 2 + bytes_read) {
/* No, move less then */
if (lseek (fd, 0, SEEK_SET) == -1) {
endwin ();
fprintf (stderr, "\nError moving file pointer "
"in back_lines().\n");
exit (-1);
}
page = buf + fpos - bytes_read;
} else { /* Move backward BUF_SIZE/2 bytes */
if (lseek (fd, -(BUF_SIZE / 2 + bytes_read),
SEEK_CUR) == -1) {
endwin ();
fprintf (stderr, "\nError moving file pointer"
" in back_lines().\n");
exit (-1);
}
page = buf + BUF_SIZE / 2;
}
if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
endwin ();
fprintf (stderr, "\nError reading file in "
"back_lines().\n");
exit (-1);
}
buf[bytes_read] = '\0';
} else { /* Beginning of file reached */
begin_reached = 1;
return;
}
}
} while (*(--page) != '\n');
page++;
}
/*
* Print a new page of text. Called by dialog_textbox().
*/
static void
print_page (WINDOW * win, int height, int width)
{
int i, passed_end = 0;
page_length = 0;
for (i = 0; i < height; i++) {
print_line (win, i, width);
if (!passed_end)
page_length++;
if (end_reached && !passed_end)
passed_end = 1;
}
wnoutrefresh (win);
}
/*
* Print a new line of text. Called by dialog_textbox() and print_page().
*/
static void
print_line (WINDOW * win, int row, int width)
{
int y, x;
char *line;
line = get_line ();
line += MIN (strlen (line), hscroll); /* Scroll horizontally */
wmove (win, row, 0); /* move cursor to correct line */
waddch (win, ' ');
waddnstr (win, line, MIN (strlen (line), width - 2));
getyx (win, y, x);
/* Clear 'residue' of previous line */
#if OLD_NCURSES
{
int i;
for (i = 0; i < width - x; i++)
waddch (win, ' ');
}
#else
wclrtoeol(win);
#endif
}
/*
* Return current line of text. Called by dialog_textbox() and print_line().
* 'page' should point to start of current line before calling, and will be
* updated to point to start of next line.
*/
static char *
get_line (void)
{
int i = 0, fpos;
static char line[MAX_LEN + 1];
end_reached = 0;
while (*page != '\n') {
if (*page == '\0') {
/* Either end of file or end of buffer reached */
if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
endwin ();
fprintf (stderr, "\nError moving file pointer in "
"get_line().\n");
exit (-1);
}
if (fpos < file_size) { /* Not end of file yet */
/* We've reached end of buffer, but not end of file yet,
so read next part of file into buffer */
if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
endwin ();
fprintf (stderr, "\nError reading file in get_line().\n");
exit (-1);
}
buf[bytes_read] = '\0';
page = buf;
} else {
if (!end_reached)
end_reached = 1;
break;
}
} else if (i < MAX_LEN)
line[i++] = *(page++);
else {
/* Truncate lines longer than MAX_LEN characters */
if (i == MAX_LEN)
line[i++] = '\0';
page++;
}
}
if (i <= MAX_LEN)
line[i] = '\0';
if (!end_reached)
page++; /* move pass '\n' */
return line;
}
/*
* Print current position
*/
static void
print_position (WINDOW * win, int height, int width)
{
int fpos, percent;
if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
endwin ();
fprintf (stderr, "\nError moving file pointer in print_position().\n");
exit (-1);
}
wattrset (win, position_indicator_attr);
wbkgdset (win, position_indicator_attr & A_COLOR);
percent = !file_size ?
100 : ((fpos - bytes_read + page - buf) * 100) / file_size;
wmove (win, height - 3, width - 9);
wprintw (win, "(%3d%%)", percent);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -