⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 textbox.c

📁 This version of dialog, formerly known as cdialog is based on the Debian package for dialog 0.9a (se
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  $Id: textbox.c,v 1.45 2003/11/26 20:41:23 tom Exp $ * *  textbox.c -- implements the text box * *  AUTHOR: Savio Lam (lam836@cs.cuhk.hk) *     and: Thomas E. Dickey * *  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 "dialog.h"typedef struct {    DIALOG_CALLBACK obj;    WINDOW *text;    const char **buttons;    int hscroll;    char line[MAX_LEN + 1];    int fd;    int file_size;    int fd_bytes_read;    int bytes_read;    int buffer_len;    bool begin_reached;    bool buffer_first;    bool end_reached;    int page_length;    int in_buf;			/* index into buf[] */    char *buf;} MY_OBJ;static longlseek_obj(MY_OBJ * obj, long offset, int mode){    long fpos;    if ((fpos = lseek(obj->fd, offset, mode)) == -1) {	switch (mode) {	case SEEK_CUR:	    dlg_exiterr("Cannot get file position");	    break;	case SEEK_END:	    dlg_exiterr("Cannot seek to end of file");	    break;	case SEEK_SET:	    dlg_exiterr("Cannot set file position to %ld", offset);	    break;	}    }    return fpos;}static longftell_obj(MY_OBJ * obj){    return lseek_obj(obj, 0, SEEK_CUR);}static char *xalloc(long size){    char *result = malloc(size);    assert_ptr(result, "xalloc");    return result;}/* * read_high() substitutes read() for tab->spaces conversion * * buffer_len, fd_bytes_read, bytes_read are modified * buf is allocated * * fd_bytes_read is the effective number of bytes read from file * bytes_read is the length of buf, that can be different if tab_correct */static voidread_high(MY_OBJ * obj, size_t size_read){    char *buftab, ch;    int i = 0, j, n, begin_line, tmpint;    /* Allocate space for read buffer */    buftab = xalloc(size_read + 1);    if ((obj->fd_bytes_read = read(obj->fd, buftab, size_read)) != -1) {	buftab[obj->fd_bytes_read] = '\0';	/* mark end of valid data */	if (dialog_vars.tab_correct) {	    /* calculate bytes_read by buftab and fd_bytes_read */	    obj->bytes_read = begin_line = 0;	    for (j = 0; j < obj->fd_bytes_read; j++)		if (buftab[j] == TAB)		    obj->bytes_read += dialog_state.tab_len			- ((obj->bytes_read - begin_line)			   % dialog_state.tab_len);		else if (buftab[j] == '\n') {		    obj->bytes_read++;		    begin_line = obj->bytes_read;		} else		    obj->bytes_read++;	    if (obj->bytes_read > obj->buffer_len) {		if (obj->buffer_first)		    obj->buffer_first = FALSE;	/* disp = 0 */		else {		    free(obj->buf);		}		obj->buffer_len = obj->bytes_read;		/* Allocate space for read buffer */		obj->buf = xalloc(obj->buffer_len + 1);	    }	} else {	    if (obj->buffer_first) {		obj->buffer_first = FALSE;		/* Allocate space for read buffer */		obj->buf = xalloc(size_read + 1);	    }	    obj->bytes_read = obj->fd_bytes_read;	}	j = 0;	begin_line = 0;	while (j < obj->fd_bytes_read)	    if (((ch = buftab[j++]) == TAB) && (dialog_vars.tab_correct != 0)) {		tmpint = dialog_state.tab_len		    - ((i - begin_line) % dialog_state.tab_len);		for (n = 0; n < tmpint; n++)		    obj->buf[i++] = ' ';	    } else {		if (ch == '\n')		    begin_line = i + 1;		obj->buf[i++] = ch;	    }	obj->buf[i] = '\0';	/* mark end of valid data */    }    if (obj->bytes_read == -1)	dlg_exiterr("Error reading file");}static inttabize(MY_OBJ * obj, int val, int pos){    long fpos;    int i, count, begin_line;    char *buftab;    if (!dialog_vars.tab_correct)	return val;    fpos = ftell_obj(obj);    lseek_obj(obj, fpos - obj->fd_bytes_read, SEEK_SET);    /* Allocate space for read buffer */    buftab = xalloc(val + 1);    if ((read(obj->fd, buftab, val)) == -1)	dlg_exiterr("Error reading file in tabize().");    begin_line = count = 0;    for (i = 0; i < val; i++) {	if (pos && count >= val) {	    count = i;		/* it's the retval */	    break;	}	if (buftab[i] == TAB)	    count += dialog_state.tab_len		- ((count - begin_line) % dialog_state.tab_len);	else if (buftab[i] == '\n') {	    count++;	    begin_line = count;	} else	    count++;    }    lseek_obj(obj, fpos, SEEK_SET);    return count;}/* * Return current line of text. * '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(MY_OBJ * obj){    int i = 0;    long fpos;    obj->end_reached = FALSE;    while (obj->buf[obj->in_buf] != '\n') {	if (obj->buf[obj->in_buf] == '\0') {	/* Either end of file or end of buffer reached */	    fpos = ftell_obj(obj);	    if (fpos < obj->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		 */		read_high(obj, BUF_SIZE);		obj->in_buf = 0;	    } else {		if (!obj->end_reached)		    obj->end_reached = TRUE;		break;	    }	} else if (i < MAX_LEN)	    obj->line[i++] = obj->buf[obj->in_buf++];	else {	    if (i == MAX_LEN)	/* Truncate lines longer than MAX_LEN characters */		obj->line[i++] = '\0';	    obj->in_buf++;	}    }    if (i <= MAX_LEN)	obj->line[i] = '\0';    if (!obj->end_reached)	obj->in_buf++;		/* move pass '\n' */    return obj->line;}static boolmatch_string(MY_OBJ * obj, char *string){    char *match = get_line(obj);    return strstr(match, string) != 0;}/* * Go back 'n' lines in text file. Called by dialog_textbox(). * 'in_buf' will be updated to point to the desired line in 'buf'. */static voidback_lines(MY_OBJ * obj, int n){    long fpos;    int i, val_to_tabize;    obj->begin_reached = FALSE;    /* 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 '--in_buf' to move one character backward so as to       * skip '\n' of the previous line */    if (!obj->end_reached) {	/* Either beginning of buffer or beginning of file reached? */	if (obj->in_buf == 0) {	    fpos = ftell_obj(obj);	    if (fpos > obj->fd_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 + obj->fd_bytes_read) {		    /* No, move less then */		    lseek_obj(obj, 0, SEEK_SET);		    val_to_tabize = fpos - obj->fd_bytes_read;		} else {	/* Move backward BUF_SIZE/2 bytes */		    lseek_obj(obj, -(BUF_SIZE / 2 + obj->fd_bytes_read), SEEK_CUR);		    val_to_tabize = BUF_SIZE / 2;		}		read_high(obj, BUF_SIZE);		obj->in_buf = tabize(obj, val_to_tabize, 0);	    } else {		/* Beginning of file reached */		obj->begin_reached = TRUE;		return;	    }	}	obj->in_buf--;	if (obj->buf[obj->in_buf] != '\n')	    /* Something's wrong... */	    dlg_exiterr("Internal error in back_lines().");    }    /* Go back 'n' lines */    for (i = 0; i < n; i++) {	do {	    if (obj->in_buf == 0) {		fpos = ftell_obj(obj);		if (fpos > obj->fd_bytes_read) {		    /* Really possible to move backward BUF_SIZE/2 bytes? */		    if (fpos < BUF_SIZE / 2 + obj->fd_bytes_read) {			/* No, move less then */			lseek_obj(obj, 0, SEEK_SET);			val_to_tabize = fpos - obj->fd_bytes_read;		    } else {	/* Move backward BUF_SIZE/2 bytes */			lseek_obj(obj, -(BUF_SIZE / 2 + obj->fd_bytes_read), SEEK_CUR);			val_to_tabize = BUF_SIZE / 2;		    }		    read_high(obj, BUF_SIZE);		    obj->in_buf = tabize(obj, val_to_tabize, 0);		} else {	/* Beginning of file reached */		    obj->begin_reached = TRUE;		    return;		}	    }	} while (obj->buf[--(obj->in_buf)] != '\n');    }    obj->in_buf++;}/* * Print a new line of text. */static voidprint_line(MY_OBJ * obj, int row, int width){    int i, y, x;    char *line;    line = get_line(obj);    line += MIN((int) strlen(line), obj->hscroll);	/* Scroll horizontally */    (void) wmove(obj->text, row, 0);	/* move cursor to correct line */    (void) waddch(obj->text, ' ');#ifdef NCURSES_VERSION    (void) waddnstr(obj->text, line, MIN((int) strlen(line), width - 2));#else    line[MIN((int) strlen(line), width - 2)] = '\0';    waddstr(obj->text, line);#endif    getyx(obj->text, y, x);    /* Clear 'residue' of previous line */    for (i = 0; i < width - x; i++)	(void) waddch(obj->text, ' ');}/* * Print a new page of text. */static voidprint_page(MY_OBJ * obj, int height, int width){    int i, passed_end = 0;    obj->page_length = 0;    for (i = 0; i < height; i++) {	print_line(obj, i, width);	if (!passed_end)	    obj->page_length++;	if (obj->end_reached && !passed_end)	    passed_end = 1;    }    (void) wnoutrefresh(obj->text);}/* * Print current position */static voidprint_position(MY_OBJ * obj, WINDOW *win, int height, int width){    long fpos;    int percent;    fpos = ftell_obj(obj);    wattrset(win, position_indicator_attr);    percent = !obj->file_size	? 100	: ((fpos	    - obj->fd_bytes_read	    + tabize(obj, obj->in_buf, 1)) * 100)	/ obj->file_size;    (void) wmove(win, height - 3, width - 9);    (void) wprintw(win, "(%3d%%)", percent);    dlg_draw_arrows(win, TRUE, TRUE, 5, 0, height - 3);}/* * Display a dialog box and get the search term from user */static intget_search_term(WINDOW *dialog, char *input, int height, int width){

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -