xref: /freebsd/contrib/dialog/progressbox.c (revision 4c8945a06b01a5c8122cdeb402af36bb46a06acc)
1*4c8945a0SNathan Whitehorn /*
2*4c8945a0SNathan Whitehorn  *  $Id: progressbox.c,v 1.8 2010/01/12 10:46:24 tom Exp $
3*4c8945a0SNathan Whitehorn  *
4*4c8945a0SNathan Whitehorn  *  progressbox.c -- implements the progress box
5*4c8945a0SNathan Whitehorn  *
6*4c8945a0SNathan Whitehorn  *  Copyright 2005	Valery Reznic
7*4c8945a0SNathan Whitehorn  *
8*4c8945a0SNathan Whitehorn  *  This program is free software; you can redistribute it and/or modify
9*4c8945a0SNathan Whitehorn  *  it under the terms of the GNU Lesser General Public License as
10*4c8945a0SNathan Whitehorn  *  published by the Free Software Foundation; either version 2.1 of the
11*4c8945a0SNathan Whitehorn  *  License, or (at your option) any later version.
12*4c8945a0SNathan Whitehorn  *
13*4c8945a0SNathan Whitehorn  *  This program is distributed in the hope that it will be useful, but
14*4c8945a0SNathan Whitehorn  *  WITHOUT ANY WARRANTY; without even the implied warranty of
15*4c8945a0SNathan Whitehorn  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16*4c8945a0SNathan Whitehorn  *  Lesser General Public License for more details.
17*4c8945a0SNathan Whitehorn  *
18*4c8945a0SNathan Whitehorn  *  You should have received a copy of the GNU Lesser General Public
19*4c8945a0SNathan Whitehorn  *  License along with this program; if not, write to
20*4c8945a0SNathan Whitehorn  *	Free Software Foundation, Inc.
21*4c8945a0SNathan Whitehorn  *	51 Franklin St., Fifth Floor
22*4c8945a0SNathan Whitehorn  *	Boston, MA 02110, USA.
23*4c8945a0SNathan Whitehorn  */
24*4c8945a0SNathan Whitehorn 
25*4c8945a0SNathan Whitehorn #include <dialog.h>
26*4c8945a0SNathan Whitehorn #include <dlg_keys.h>
27*4c8945a0SNathan Whitehorn 
28*4c8945a0SNathan Whitehorn #define MIN_HIGH (4)
29*4c8945a0SNathan Whitehorn #define MIN_WIDE (10 + 2 * (2 + MARGIN))
30*4c8945a0SNathan Whitehorn 
31*4c8945a0SNathan Whitehorn typedef struct {
32*4c8945a0SNathan Whitehorn     DIALOG_CALLBACK obj;
33*4c8945a0SNathan Whitehorn     WINDOW *text;
34*4c8945a0SNathan Whitehorn     char line[MAX_LEN + 1];
35*4c8945a0SNathan Whitehorn     int is_eof;
36*4c8945a0SNathan Whitehorn } MY_OBJ;
37*4c8945a0SNathan Whitehorn 
38*4c8945a0SNathan Whitehorn /*
39*4c8945a0SNathan Whitehorn  * Return current line of text.
40*4c8945a0SNathan Whitehorn  */
41*4c8945a0SNathan Whitehorn static char *
42*4c8945a0SNathan Whitehorn get_line(MY_OBJ * obj)
43*4c8945a0SNathan Whitehorn {
44*4c8945a0SNathan Whitehorn     FILE *fp = obj->obj.input;
45*4c8945a0SNathan Whitehorn     int col = 0;
46*4c8945a0SNathan Whitehorn     int j, tmpint, ch;
47*4c8945a0SNathan Whitehorn 
48*4c8945a0SNathan Whitehorn     while (1) {
49*4c8945a0SNathan Whitehorn 	if ((ch = getc(fp)) == EOF) {
50*4c8945a0SNathan Whitehorn 	    obj->is_eof = 1;
51*4c8945a0SNathan Whitehorn 	    if (col) {
52*4c8945a0SNathan Whitehorn 		break;
53*4c8945a0SNathan Whitehorn 	    } else {
54*4c8945a0SNathan Whitehorn 		return NULL;
55*4c8945a0SNathan Whitehorn 	    }
56*4c8945a0SNathan Whitehorn 	}
57*4c8945a0SNathan Whitehorn 	if (ch == '\n')
58*4c8945a0SNathan Whitehorn 	    break;
59*4c8945a0SNathan Whitehorn 	if (ch == '\r')
60*4c8945a0SNathan Whitehorn 	    break;
61*4c8945a0SNathan Whitehorn 	if ((ch == TAB) && (dialog_vars.tab_correct)) {
62*4c8945a0SNathan Whitehorn 	    tmpint = dialog_state.tab_len
63*4c8945a0SNathan Whitehorn 		- (col % dialog_state.tab_len);
64*4c8945a0SNathan Whitehorn 	    for (j = 0; j < tmpint; j++) {
65*4c8945a0SNathan Whitehorn 		if (col < MAX_LEN)
66*4c8945a0SNathan Whitehorn 		    obj->line[col] = ' ';
67*4c8945a0SNathan Whitehorn 		++col;
68*4c8945a0SNathan Whitehorn 	    }
69*4c8945a0SNathan Whitehorn 	} else {
70*4c8945a0SNathan Whitehorn 	    obj->line[col] = (char) ch;
71*4c8945a0SNathan Whitehorn 	    ++col;
72*4c8945a0SNathan Whitehorn 	}
73*4c8945a0SNathan Whitehorn 	if (col >= MAX_LEN)
74*4c8945a0SNathan Whitehorn 	    break;
75*4c8945a0SNathan Whitehorn     }
76*4c8945a0SNathan Whitehorn 
77*4c8945a0SNathan Whitehorn     obj->line[col] = '\0';
78*4c8945a0SNathan Whitehorn 
79*4c8945a0SNathan Whitehorn     return obj->line;
80*4c8945a0SNathan Whitehorn }
81*4c8945a0SNathan Whitehorn 
82*4c8945a0SNathan Whitehorn /*
83*4c8945a0SNathan Whitehorn  * Print a new line of text.
84*4c8945a0SNathan Whitehorn  */
85*4c8945a0SNathan Whitehorn static void
86*4c8945a0SNathan Whitehorn print_line(MY_OBJ * obj, WINDOW *win, int row, int width)
87*4c8945a0SNathan Whitehorn {
88*4c8945a0SNathan Whitehorn     int i, y, x;
89*4c8945a0SNathan Whitehorn     char *line = obj->line;
90*4c8945a0SNathan Whitehorn 
91*4c8945a0SNathan Whitehorn     (void) wmove(win, row, 0);	/* move cursor to correct line */
92*4c8945a0SNathan Whitehorn     (void) waddch(win, ' ');
93*4c8945a0SNathan Whitehorn #ifdef NCURSES_VERSION
94*4c8945a0SNathan Whitehorn     (void) waddnstr(win, line, MIN((int) strlen(line), width - 2));
95*4c8945a0SNathan Whitehorn #else
96*4c8945a0SNathan Whitehorn     line[MIN((int) strlen(line), width - 2)] = '\0';
97*4c8945a0SNathan Whitehorn     waddstr(win, line);
98*4c8945a0SNathan Whitehorn #endif
99*4c8945a0SNathan Whitehorn 
100*4c8945a0SNathan Whitehorn     getyx(win, y, x);
101*4c8945a0SNathan Whitehorn     /* Clear 'residue' of previous line */
102*4c8945a0SNathan Whitehorn     for (i = 0; i < width - x; i++)
103*4c8945a0SNathan Whitehorn 	(void) waddch(win, ' ');
104*4c8945a0SNathan Whitehorn }
105*4c8945a0SNathan Whitehorn 
106*4c8945a0SNathan Whitehorn /*
107*4c8945a0SNathan Whitehorn  * Display text from a stdin in a scrolling window.
108*4c8945a0SNathan Whitehorn  */
109*4c8945a0SNathan Whitehorn int
110*4c8945a0SNathan Whitehorn dialog_progressbox(const char *title, const char *cprompt, int height, int width)
111*4c8945a0SNathan Whitehorn {
112*4c8945a0SNathan Whitehorn     int i;
113*4c8945a0SNathan Whitehorn     int x, y, thigh;
114*4c8945a0SNathan Whitehorn     WINDOW *dialog, *text;
115*4c8945a0SNathan Whitehorn     MY_OBJ *obj;
116*4c8945a0SNathan Whitehorn     FILE *fd = dialog_state.pipe_input;
117*4c8945a0SNathan Whitehorn     char *prompt = dlg_strclone(cprompt);
118*4c8945a0SNathan Whitehorn 
119*4c8945a0SNathan Whitehorn     dlg_tab_correct_str(prompt);
120*4c8945a0SNathan Whitehorn     dlg_auto_size(title, prompt, &height, &width, MIN_HIGH, MIN_WIDE);
121*4c8945a0SNathan Whitehorn     dlg_print_size(height, width);
122*4c8945a0SNathan Whitehorn     dlg_ctl_size(height, width);
123*4c8945a0SNathan Whitehorn 
124*4c8945a0SNathan Whitehorn     x = dlg_box_x_ordinate(width);
125*4c8945a0SNathan Whitehorn     y = dlg_box_y_ordinate(height);
126*4c8945a0SNathan Whitehorn     thigh = height - (2 * MARGIN);
127*4c8945a0SNathan Whitehorn 
128*4c8945a0SNathan Whitehorn     dialog = dlg_new_window(height, width, y, x);
129*4c8945a0SNathan Whitehorn 
130*4c8945a0SNathan Whitehorn     dlg_draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
131*4c8945a0SNathan Whitehorn     dlg_draw_title(dialog, title);
132*4c8945a0SNathan Whitehorn 
133*4c8945a0SNathan Whitehorn     if (*prompt != '\0') {
134*4c8945a0SNathan Whitehorn 	int y2, x2;
135*4c8945a0SNathan Whitehorn 
136*4c8945a0SNathan Whitehorn 	wattrset(dialog, dialog_attr);
137*4c8945a0SNathan Whitehorn 	dlg_print_autowrap(dialog, prompt, height, width);
138*4c8945a0SNathan Whitehorn 	getyx(dialog, y2, x2);
139*4c8945a0SNathan Whitehorn 	++y2;
140*4c8945a0SNathan Whitehorn 	wmove(dialog, y2, MARGIN);
141*4c8945a0SNathan Whitehorn 	for (i = 0; i < getmaxx(dialog) - 2 * MARGIN; i++)
142*4c8945a0SNathan Whitehorn 	    (void) waddch(dialog, dlg_boxchar(ACS_HLINE));
143*4c8945a0SNathan Whitehorn 	y += y2;
144*4c8945a0SNathan Whitehorn 	thigh -= y2;
145*4c8945a0SNathan Whitehorn     }
146*4c8945a0SNathan Whitehorn 
147*4c8945a0SNathan Whitehorn     /* Create window for text region, used for scrolling text */
148*4c8945a0SNathan Whitehorn     text = dlg_sub_window(dialog,
149*4c8945a0SNathan Whitehorn 			  thigh,
150*4c8945a0SNathan Whitehorn 			  width - (2 * MARGIN),
151*4c8945a0SNathan Whitehorn 			  y + MARGIN,
152*4c8945a0SNathan Whitehorn 			  x + MARGIN);
153*4c8945a0SNathan Whitehorn 
154*4c8945a0SNathan Whitehorn     (void) wrefresh(dialog);
155*4c8945a0SNathan Whitehorn 
156*4c8945a0SNathan Whitehorn     (void) wmove(dialog, thigh, (MARGIN + 1));
157*4c8945a0SNathan Whitehorn     (void) wnoutrefresh(dialog);
158*4c8945a0SNathan Whitehorn 
159*4c8945a0SNathan Whitehorn     obj = dlg_calloc(MY_OBJ, 1);
160*4c8945a0SNathan Whitehorn     assert_ptr(obj, "dialog_progressbox");
161*4c8945a0SNathan Whitehorn 
162*4c8945a0SNathan Whitehorn     obj->obj.input = fd;
163*4c8945a0SNathan Whitehorn     obj->obj.win = dialog;
164*4c8945a0SNathan Whitehorn     obj->text = text;
165*4c8945a0SNathan Whitehorn 
166*4c8945a0SNathan Whitehorn     dlg_attr_clear(text, thigh, getmaxx(text), dialog_attr);
167*4c8945a0SNathan Whitehorn     for (i = 0; get_line(obj); i++) {
168*4c8945a0SNathan Whitehorn 	if (i < thigh) {
169*4c8945a0SNathan Whitehorn 	    print_line(obj, text, i, width - (2 * MARGIN));
170*4c8945a0SNathan Whitehorn 	} else {
171*4c8945a0SNathan Whitehorn 	    scrollok(text, TRUE);
172*4c8945a0SNathan Whitehorn 	    scroll(text);
173*4c8945a0SNathan Whitehorn 	    scrollok(text, FALSE);
174*4c8945a0SNathan Whitehorn 	    print_line(obj, text, thigh - 1, width - (2 * MARGIN));
175*4c8945a0SNathan Whitehorn 	}
176*4c8945a0SNathan Whitehorn 	(void) wnoutrefresh(text);
177*4c8945a0SNathan Whitehorn 	(void) wrefresh(text);
178*4c8945a0SNathan Whitehorn 	if (obj->is_eof)
179*4c8945a0SNathan Whitehorn 	    break;
180*4c8945a0SNathan Whitehorn     }
181*4c8945a0SNathan Whitehorn     dlg_unregister_window(text);
182*4c8945a0SNathan Whitehorn     dlg_del_window(dialog);
183*4c8945a0SNathan Whitehorn     free(prompt);
184*4c8945a0SNathan Whitehorn     free(obj);
185*4c8945a0SNathan Whitehorn 
186*4c8945a0SNathan Whitehorn     return DLG_EXIT_OK;
187*4c8945a0SNathan Whitehorn }
188