1217309Snwhitehorn/* 2251843Sbapt * $Id: progressbox.c,v 1.23 2012/12/21 10:00:05 tom Exp $ 3217309Snwhitehorn * 4217309Snwhitehorn * progressbox.c -- implements the progress box 5217309Snwhitehorn * 6217309Snwhitehorn * Copyright 2005 Valery Reznic 7251843Sbapt * Copyright 2006-2012 Thomas E. Dickey 8217309Snwhitehorn * 9217309Snwhitehorn * This program is free software; you can redistribute it and/or modify 10217309Snwhitehorn * it under the terms of the GNU Lesser General Public License as 11217309Snwhitehorn * published by the Free Software Foundation; either version 2.1 of the 12217309Snwhitehorn * License, or (at your option) any later version. 13217309Snwhitehorn * 14217309Snwhitehorn * This program is distributed in the hope that it will be useful, but 15217309Snwhitehorn * WITHOUT ANY WARRANTY; without even the implied warranty of 16217309Snwhitehorn * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17217309Snwhitehorn * Lesser General Public License for more details. 18217309Snwhitehorn * 19217309Snwhitehorn * You should have received a copy of the GNU Lesser General Public 20217309Snwhitehorn * License along with this program; if not, write to 21217309Snwhitehorn * Free Software Foundation, Inc. 22217309Snwhitehorn * 51 Franklin St., Fifth Floor 23217309Snwhitehorn * Boston, MA 02110, USA. 24217309Snwhitehorn */ 25217309Snwhitehorn 26217309Snwhitehorn#include <dialog.h> 27217309Snwhitehorn#include <dlg_keys.h> 28217309Snwhitehorn 29217309Snwhitehorn#define MIN_HIGH (4) 30217309Snwhitehorn#define MIN_WIDE (10 + 2 * (2 + MARGIN)) 31217309Snwhitehorn 32217309Snwhitehorntypedef struct { 33217309Snwhitehorn DIALOG_CALLBACK obj; 34217309Snwhitehorn WINDOW *text; 35217309Snwhitehorn char line[MAX_LEN + 1]; 36217309Snwhitehorn int is_eof; 37217309Snwhitehorn} MY_OBJ; 38217309Snwhitehorn 39217309Snwhitehorn/* 40217309Snwhitehorn * Return current line of text. 41217309Snwhitehorn */ 42217309Snwhitehornstatic char * 43217309Snwhitehornget_line(MY_OBJ * obj) 44217309Snwhitehorn{ 45217309Snwhitehorn FILE *fp = obj->obj.input; 46217309Snwhitehorn int col = 0; 47217309Snwhitehorn int j, tmpint, ch; 48217309Snwhitehorn 49251843Sbapt for (;;) { 50217309Snwhitehorn if ((ch = getc(fp)) == EOF) { 51217309Snwhitehorn obj->is_eof = 1; 52217309Snwhitehorn if (col) { 53217309Snwhitehorn break; 54217309Snwhitehorn } else { 55217309Snwhitehorn return NULL; 56217309Snwhitehorn } 57217309Snwhitehorn } 58217309Snwhitehorn if (ch == '\n') 59217309Snwhitehorn break; 60217309Snwhitehorn if (ch == '\r') 61217309Snwhitehorn break; 62251843Sbapt if (col >= MAX_LEN) 63251843Sbapt continue; 64217309Snwhitehorn if ((ch == TAB) && (dialog_vars.tab_correct)) { 65217309Snwhitehorn tmpint = dialog_state.tab_len 66217309Snwhitehorn - (col % dialog_state.tab_len); 67217309Snwhitehorn for (j = 0; j < tmpint; j++) { 68251843Sbapt if (col < MAX_LEN) { 69217309Snwhitehorn obj->line[col] = ' '; 70251843Sbapt ++col; 71251843Sbapt } else { 72251843Sbapt break; 73251843Sbapt } 74217309Snwhitehorn } 75217309Snwhitehorn } else { 76217309Snwhitehorn obj->line[col] = (char) ch; 77217309Snwhitehorn ++col; 78217309Snwhitehorn } 79217309Snwhitehorn } 80217309Snwhitehorn 81217309Snwhitehorn obj->line[col] = '\0'; 82217309Snwhitehorn 83217309Snwhitehorn return obj->line; 84217309Snwhitehorn} 85217309Snwhitehorn 86217309Snwhitehorn/* 87217309Snwhitehorn * Print a new line of text. 88217309Snwhitehorn */ 89217309Snwhitehornstatic void 90217309Snwhitehornprint_line(MY_OBJ * obj, WINDOW *win, int row, int width) 91217309Snwhitehorn{ 92217309Snwhitehorn int i, y, x; 93217309Snwhitehorn char *line = obj->line; 94217309Snwhitehorn 95217309Snwhitehorn (void) wmove(win, row, 0); /* move cursor to correct line */ 96217309Snwhitehorn (void) waddch(win, ' '); 97217309Snwhitehorn#ifdef NCURSES_VERSION 98217309Snwhitehorn (void) waddnstr(win, line, MIN((int) strlen(line), width - 2)); 99217309Snwhitehorn#else 100217309Snwhitehorn line[MIN((int) strlen(line), width - 2)] = '\0'; 101217309Snwhitehorn waddstr(win, line); 102217309Snwhitehorn#endif 103217309Snwhitehorn 104217309Snwhitehorn getyx(win, y, x); 105251843Sbapt (void) y; 106217309Snwhitehorn /* Clear 'residue' of previous line */ 107217309Snwhitehorn for (i = 0; i < width - x; i++) 108217309Snwhitehorn (void) waddch(win, ' '); 109217309Snwhitehorn} 110217309Snwhitehorn 111220749Snwhitehornstatic int 112220749Snwhitehornpause_for_ok(WINDOW *dialog, int height, int width) 113220749Snwhitehorn{ 114220749Snwhitehorn /* *INDENT-OFF* */ 115220749Snwhitehorn static DLG_KEYS_BINDING binding[] = { 116224014Snwhitehorn HELPKEY_BINDINGS, 117220749Snwhitehorn ENTERKEY_BINDINGS, 118251843Sbapt TRAVERSE_BINDINGS, 119220749Snwhitehorn END_KEYS_BINDING 120220749Snwhitehorn }; 121220749Snwhitehorn /* *INDENT-ON* */ 122220749Snwhitehorn 123251843Sbapt int button; 124220749Snwhitehorn int key = 0, fkey; 125220749Snwhitehorn int result = DLG_EXIT_UNKNOWN; 126220749Snwhitehorn const char **buttons = dlg_ok_label(); 127220749Snwhitehorn int check; 128251843Sbapt int save_nocancel = dialog_vars.nocancel; 129251843Sbapt bool redraw = TRUE; 130220749Snwhitehorn 131251843Sbapt dialog_vars.nocancel = TRUE; 132251843Sbapt button = dlg_default_button(); 133251843Sbapt 134220749Snwhitehorn dlg_register_window(dialog, "progressbox", binding); 135220749Snwhitehorn dlg_register_buttons(dialog, "progressbox", buttons); 136220749Snwhitehorn 137251843Sbapt dlg_draw_bottom_box2(dialog, border_attr, border2_attr, dialog_attr); 138220749Snwhitehorn mouse_mkbutton(height - 2, width / 2 - 4, 6, '\n'); 139220749Snwhitehorn 140220749Snwhitehorn while (result == DLG_EXIT_UNKNOWN) { 141251843Sbapt if (redraw) { 142251843Sbapt redraw = FALSE; 143251843Sbapt if (button < 0) 144251843Sbapt button = 0; 145251843Sbapt dlg_draw_buttons(dialog, 146251843Sbapt height - 2, 0, 147251843Sbapt buttons, button, 148251843Sbapt FALSE, width); 149251843Sbapt } 150251843Sbapt 151220749Snwhitehorn key = dlg_mouse_wgetch(dialog, &fkey); 152220749Snwhitehorn if (dlg_result_key(key, fkey, &result)) 153220749Snwhitehorn break; 154220749Snwhitehorn 155220749Snwhitehorn if (!fkey && (check = dlg_char_to_button(key, buttons)) >= 0) { 156251843Sbapt result = dlg_ok_buttoncode(check); 157220749Snwhitehorn break; 158220749Snwhitehorn } 159220749Snwhitehorn 160220749Snwhitehorn if (fkey) { 161220749Snwhitehorn switch (key) { 162251843Sbapt case DLGK_FIELD_NEXT: 163251843Sbapt button = dlg_next_button(buttons, button); 164251843Sbapt redraw = TRUE; 165220749Snwhitehorn break; 166251843Sbapt case DLGK_FIELD_PREV: 167251843Sbapt button = dlg_prev_button(buttons, button); 168251843Sbapt redraw = TRUE; 169220749Snwhitehorn break; 170251843Sbapt case DLGK_ENTER: 171251843Sbapt result = dlg_ok_buttoncode(button); 172220749Snwhitehorn break; 173220749Snwhitehorn default: 174251843Sbapt if (is_DLGK_MOUSE(key)) { 175251843Sbapt result = dlg_ok_buttoncode(key - M_EVENT); 176251843Sbapt if (result < 0) 177251843Sbapt result = DLG_EXIT_OK; 178251843Sbapt } else { 179251843Sbapt beep(); 180251843Sbapt } 181220749Snwhitehorn break; 182220749Snwhitehorn } 183251843Sbapt 184220749Snwhitehorn } else { 185220749Snwhitehorn beep(); 186220749Snwhitehorn } 187220749Snwhitehorn } 188220749Snwhitehorn dlg_unregister_window(dialog); 189251843Sbapt 190251843Sbapt dialog_vars.nocancel = save_nocancel; 191220749Snwhitehorn return result; 192220749Snwhitehorn} 193220749Snwhitehorn 194217309Snwhitehornint 195220749Snwhitehorndlg_progressbox(const char *title, 196220749Snwhitehorn const char *cprompt, 197220749Snwhitehorn int height, 198220749Snwhitehorn int width, 199220749Snwhitehorn int pauseopt, 200220749Snwhitehorn FILE *fp) 201217309Snwhitehorn{ 202217309Snwhitehorn int i; 203217309Snwhitehorn int x, y, thigh; 204217309Snwhitehorn WINDOW *dialog, *text; 205217309Snwhitehorn MY_OBJ *obj; 206217309Snwhitehorn char *prompt = dlg_strclone(cprompt); 207220749Snwhitehorn int result; 208217309Snwhitehorn 209217309Snwhitehorn dlg_tab_correct_str(prompt); 210217309Snwhitehorn dlg_auto_size(title, prompt, &height, &width, MIN_HIGH, MIN_WIDE); 211217309Snwhitehorn dlg_print_size(height, width); 212217309Snwhitehorn dlg_ctl_size(height, width); 213217309Snwhitehorn 214217309Snwhitehorn x = dlg_box_x_ordinate(width); 215217309Snwhitehorn y = dlg_box_y_ordinate(height); 216217309Snwhitehorn thigh = height - (2 * MARGIN); 217217309Snwhitehorn 218217309Snwhitehorn dialog = dlg_new_window(height, width, y, x); 219217309Snwhitehorn 220251843Sbapt dlg_draw_box2(dialog, 0, 0, height, width, dialog_attr, border_attr, border2_attr); 221217309Snwhitehorn dlg_draw_title(dialog, title); 222224014Snwhitehorn dlg_draw_helpline(dialog, FALSE); 223217309Snwhitehorn 224217309Snwhitehorn if (*prompt != '\0') { 225217309Snwhitehorn int y2, x2; 226217309Snwhitehorn 227251843Sbapt (void) wattrset(dialog, dialog_attr); 228217309Snwhitehorn dlg_print_autowrap(dialog, prompt, height, width); 229217309Snwhitehorn getyx(dialog, y2, x2); 230251843Sbapt (void) x2; 231217309Snwhitehorn ++y2; 232217309Snwhitehorn wmove(dialog, y2, MARGIN); 233217309Snwhitehorn for (i = 0; i < getmaxx(dialog) - 2 * MARGIN; i++) 234217309Snwhitehorn (void) waddch(dialog, dlg_boxchar(ACS_HLINE)); 235217309Snwhitehorn y += y2; 236217309Snwhitehorn thigh -= y2; 237217309Snwhitehorn } 238217309Snwhitehorn 239217309Snwhitehorn /* Create window for text region, used for scrolling text */ 240217309Snwhitehorn text = dlg_sub_window(dialog, 241217309Snwhitehorn thigh, 242217309Snwhitehorn width - (2 * MARGIN), 243217309Snwhitehorn y + MARGIN, 244217309Snwhitehorn x + MARGIN); 245217309Snwhitehorn 246217309Snwhitehorn (void) wrefresh(dialog); 247217309Snwhitehorn 248217309Snwhitehorn (void) wmove(dialog, thigh, (MARGIN + 1)); 249217309Snwhitehorn (void) wnoutrefresh(dialog); 250217309Snwhitehorn 251217309Snwhitehorn obj = dlg_calloc(MY_OBJ, 1); 252220749Snwhitehorn assert_ptr(obj, "dlg_progressbox"); 253217309Snwhitehorn 254220749Snwhitehorn obj->obj.input = fp; 255217309Snwhitehorn obj->obj.win = dialog; 256217309Snwhitehorn obj->text = text; 257217309Snwhitehorn 258217309Snwhitehorn dlg_attr_clear(text, thigh, getmaxx(text), dialog_attr); 259217309Snwhitehorn for (i = 0; get_line(obj); i++) { 260217309Snwhitehorn if (i < thigh) { 261217309Snwhitehorn print_line(obj, text, i, width - (2 * MARGIN)); 262217309Snwhitehorn } else { 263217309Snwhitehorn scrollok(text, TRUE); 264217309Snwhitehorn scroll(text); 265217309Snwhitehorn scrollok(text, FALSE); 266217309Snwhitehorn print_line(obj, text, thigh - 1, width - (2 * MARGIN)); 267217309Snwhitehorn } 268217309Snwhitehorn (void) wrefresh(text); 269251843Sbapt dlg_trace_win(dialog); 270217309Snwhitehorn if (obj->is_eof) 271217309Snwhitehorn break; 272217309Snwhitehorn } 273220749Snwhitehorn 274220749Snwhitehorn if (pauseopt) { 275220749Snwhitehorn scrollok(text, TRUE); 276220749Snwhitehorn wscrl(text, 1 + MARGIN); 277220749Snwhitehorn (void) wrefresh(text); 278220749Snwhitehorn result = pause_for_ok(dialog, height, width); 279220749Snwhitehorn } else { 280220749Snwhitehorn wrefresh(dialog); 281220749Snwhitehorn result = DLG_EXIT_OK; 282220749Snwhitehorn } 283220749Snwhitehorn 284217309Snwhitehorn dlg_del_window(dialog); 285217309Snwhitehorn free(prompt); 286217309Snwhitehorn free(obj); 287217309Snwhitehorn 288251843Sbapt return result; 289217309Snwhitehorn} 290220749Snwhitehorn 291220749Snwhitehorn/* 292220749Snwhitehorn * Display text from a stdin in a scrolling window. 293220749Snwhitehorn */ 294220749Snwhitehornint 295220749Snwhitehorndialog_progressbox(const char *title, const char *cprompt, int height, int width) 296220749Snwhitehorn{ 297220749Snwhitehorn int result; 298220749Snwhitehorn result = dlg_progressbox(title, 299220749Snwhitehorn cprompt, 300220749Snwhitehorn height, 301220749Snwhitehorn width, 302220749Snwhitehorn FALSE, 303220749Snwhitehorn dialog_state.pipe_input); 304220749Snwhitehorn dialog_state.pipe_input = 0; 305220749Snwhitehorn return result; 306220749Snwhitehorn} 307