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