14c8945a0SNathan Whitehorn /* 2*682c9e0fSNathan Whitehorn * $Id: progressbox.c,v 1.13 2011/06/27 08:18:20 tom Exp $ 34c8945a0SNathan Whitehorn * 44c8945a0SNathan Whitehorn * progressbox.c -- implements the progress box 54c8945a0SNathan Whitehorn * 64c8945a0SNathan Whitehorn * Copyright 2005 Valery Reznic 77a1c0d96SNathan Whitehorn * Copyright 2006-2011 Thomas E. Dickey 84c8945a0SNathan Whitehorn * 94c8945a0SNathan Whitehorn * This program is free software; you can redistribute it and/or modify 104c8945a0SNathan Whitehorn * it under the terms of the GNU Lesser General Public License as 114c8945a0SNathan Whitehorn * published by the Free Software Foundation; either version 2.1 of the 124c8945a0SNathan Whitehorn * License, or (at your option) any later version. 134c8945a0SNathan Whitehorn * 144c8945a0SNathan Whitehorn * This program is distributed in the hope that it will be useful, but 154c8945a0SNathan Whitehorn * WITHOUT ANY WARRANTY; without even the implied warranty of 164c8945a0SNathan Whitehorn * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 174c8945a0SNathan Whitehorn * Lesser General Public License for more details. 184c8945a0SNathan Whitehorn * 194c8945a0SNathan Whitehorn * You should have received a copy of the GNU Lesser General Public 204c8945a0SNathan Whitehorn * License along with this program; if not, write to 214c8945a0SNathan Whitehorn * Free Software Foundation, Inc. 224c8945a0SNathan Whitehorn * 51 Franklin St., Fifth Floor 234c8945a0SNathan Whitehorn * Boston, MA 02110, USA. 244c8945a0SNathan Whitehorn */ 254c8945a0SNathan Whitehorn 264c8945a0SNathan Whitehorn #include <dialog.h> 274c8945a0SNathan Whitehorn #include <dlg_keys.h> 284c8945a0SNathan Whitehorn 294c8945a0SNathan Whitehorn #define MIN_HIGH (4) 304c8945a0SNathan Whitehorn #define MIN_WIDE (10 + 2 * (2 + MARGIN)) 314c8945a0SNathan Whitehorn 324c8945a0SNathan Whitehorn typedef struct { 334c8945a0SNathan Whitehorn DIALOG_CALLBACK obj; 344c8945a0SNathan Whitehorn WINDOW *text; 354c8945a0SNathan Whitehorn char line[MAX_LEN + 1]; 364c8945a0SNathan Whitehorn int is_eof; 374c8945a0SNathan Whitehorn } MY_OBJ; 384c8945a0SNathan Whitehorn 394c8945a0SNathan Whitehorn /* 404c8945a0SNathan Whitehorn * Return current line of text. 414c8945a0SNathan Whitehorn */ 424c8945a0SNathan Whitehorn static char * 434c8945a0SNathan Whitehorn get_line(MY_OBJ * obj) 444c8945a0SNathan Whitehorn { 454c8945a0SNathan Whitehorn FILE *fp = obj->obj.input; 464c8945a0SNathan Whitehorn int col = 0; 474c8945a0SNathan Whitehorn int j, tmpint, ch; 484c8945a0SNathan Whitehorn 494c8945a0SNathan Whitehorn while (1) { 504c8945a0SNathan Whitehorn if ((ch = getc(fp)) == EOF) { 514c8945a0SNathan Whitehorn obj->is_eof = 1; 524c8945a0SNathan Whitehorn if (col) { 534c8945a0SNathan Whitehorn break; 544c8945a0SNathan Whitehorn } else { 554c8945a0SNathan Whitehorn return NULL; 564c8945a0SNathan Whitehorn } 574c8945a0SNathan Whitehorn } 584c8945a0SNathan Whitehorn if (ch == '\n') 594c8945a0SNathan Whitehorn break; 604c8945a0SNathan Whitehorn if (ch == '\r') 614c8945a0SNathan Whitehorn break; 624c8945a0SNathan Whitehorn if ((ch == TAB) && (dialog_vars.tab_correct)) { 634c8945a0SNathan Whitehorn tmpint = dialog_state.tab_len 644c8945a0SNathan Whitehorn - (col % dialog_state.tab_len); 654c8945a0SNathan Whitehorn for (j = 0; j < tmpint; j++) { 664c8945a0SNathan Whitehorn if (col < MAX_LEN) 674c8945a0SNathan Whitehorn obj->line[col] = ' '; 684c8945a0SNathan Whitehorn ++col; 694c8945a0SNathan Whitehorn } 704c8945a0SNathan Whitehorn } else { 714c8945a0SNathan Whitehorn obj->line[col] = (char) ch; 724c8945a0SNathan Whitehorn ++col; 734c8945a0SNathan Whitehorn } 744c8945a0SNathan Whitehorn if (col >= MAX_LEN) 754c8945a0SNathan Whitehorn break; 764c8945a0SNathan Whitehorn } 774c8945a0SNathan Whitehorn 784c8945a0SNathan Whitehorn obj->line[col] = '\0'; 794c8945a0SNathan Whitehorn 804c8945a0SNathan Whitehorn return obj->line; 814c8945a0SNathan Whitehorn } 824c8945a0SNathan Whitehorn 834c8945a0SNathan Whitehorn /* 844c8945a0SNathan Whitehorn * Print a new line of text. 854c8945a0SNathan Whitehorn */ 864c8945a0SNathan Whitehorn static void 874c8945a0SNathan Whitehorn print_line(MY_OBJ * obj, WINDOW *win, int row, int width) 884c8945a0SNathan Whitehorn { 894c8945a0SNathan Whitehorn int i, y, x; 904c8945a0SNathan Whitehorn char *line = obj->line; 914c8945a0SNathan Whitehorn 924c8945a0SNathan Whitehorn (void) wmove(win, row, 0); /* move cursor to correct line */ 934c8945a0SNathan Whitehorn (void) waddch(win, ' '); 944c8945a0SNathan Whitehorn #ifdef NCURSES_VERSION 954c8945a0SNathan Whitehorn (void) waddnstr(win, line, MIN((int) strlen(line), width - 2)); 964c8945a0SNathan Whitehorn #else 974c8945a0SNathan Whitehorn line[MIN((int) strlen(line), width - 2)] = '\0'; 984c8945a0SNathan Whitehorn waddstr(win, line); 994c8945a0SNathan Whitehorn #endif 1004c8945a0SNathan Whitehorn 1014c8945a0SNathan Whitehorn getyx(win, y, x); 1024c8945a0SNathan Whitehorn /* Clear 'residue' of previous line */ 1034c8945a0SNathan Whitehorn for (i = 0; i < width - x; i++) 1044c8945a0SNathan Whitehorn (void) waddch(win, ' '); 1054c8945a0SNathan Whitehorn } 1064c8945a0SNathan Whitehorn 1077a1c0d96SNathan Whitehorn static int 1087a1c0d96SNathan Whitehorn pause_for_ok(WINDOW *dialog, int height, int width) 1097a1c0d96SNathan Whitehorn { 1107a1c0d96SNathan Whitehorn /* *INDENT-OFF* */ 1117a1c0d96SNathan Whitehorn static DLG_KEYS_BINDING binding[] = { 112*682c9e0fSNathan Whitehorn HELPKEY_BINDINGS, 1137a1c0d96SNathan Whitehorn ENTERKEY_BINDINGS, 1147a1c0d96SNathan Whitehorn DLG_KEYS_DATA( DLGK_ENTER, ' ' ), 1157a1c0d96SNathan Whitehorn END_KEYS_BINDING 1167a1c0d96SNathan Whitehorn }; 1177a1c0d96SNathan Whitehorn /* *INDENT-ON* */ 1187a1c0d96SNathan Whitehorn 1197a1c0d96SNathan Whitehorn int button = 0; 1207a1c0d96SNathan Whitehorn int key = 0, fkey; 1217a1c0d96SNathan Whitehorn int result = DLG_EXIT_UNKNOWN; 1227a1c0d96SNathan Whitehorn const char **buttons = dlg_ok_label(); 1237a1c0d96SNathan Whitehorn int check; 1247a1c0d96SNathan Whitehorn 1257a1c0d96SNathan Whitehorn dlg_register_window(dialog, "progressbox", binding); 1267a1c0d96SNathan Whitehorn dlg_register_buttons(dialog, "progressbox", buttons); 1277a1c0d96SNathan Whitehorn 1287a1c0d96SNathan Whitehorn dlg_draw_bottom_box(dialog); 1297a1c0d96SNathan Whitehorn mouse_mkbutton(height - 2, width / 2 - 4, 6, '\n'); 1307a1c0d96SNathan Whitehorn dlg_draw_buttons(dialog, height - 2, 0, buttons, button, FALSE, width); 1317a1c0d96SNathan Whitehorn 1327a1c0d96SNathan Whitehorn while (result == DLG_EXIT_UNKNOWN) { 1337a1c0d96SNathan Whitehorn key = dlg_mouse_wgetch(dialog, &fkey); 1347a1c0d96SNathan Whitehorn if (dlg_result_key(key, fkey, &result)) 1357a1c0d96SNathan Whitehorn break; 1367a1c0d96SNathan Whitehorn 1377a1c0d96SNathan Whitehorn if (!fkey && (check = dlg_char_to_button(key, buttons)) >= 0) { 1387a1c0d96SNathan Whitehorn result = check ? DLG_EXIT_HELP : DLG_EXIT_OK; 1397a1c0d96SNathan Whitehorn break; 1407a1c0d96SNathan Whitehorn } 1417a1c0d96SNathan Whitehorn 1427a1c0d96SNathan Whitehorn if (fkey) { 1437a1c0d96SNathan Whitehorn switch (key) { 1447a1c0d96SNathan Whitehorn case DLGK_ENTER: 1457a1c0d96SNathan Whitehorn result = button ? DLG_EXIT_HELP : DLG_EXIT_OK; 1467a1c0d96SNathan Whitehorn break; 1477a1c0d96SNathan Whitehorn case DLGK_MOUSE(0): 1487a1c0d96SNathan Whitehorn result = DLG_EXIT_OK; 1497a1c0d96SNathan Whitehorn break; 1507a1c0d96SNathan Whitehorn case DLGK_MOUSE(1): 1517a1c0d96SNathan Whitehorn result = DLG_EXIT_HELP; 1527a1c0d96SNathan Whitehorn break; 1537a1c0d96SNathan Whitehorn default: 1547a1c0d96SNathan Whitehorn beep(); 1557a1c0d96SNathan Whitehorn break; 1567a1c0d96SNathan Whitehorn } 1577a1c0d96SNathan Whitehorn } else { 1587a1c0d96SNathan Whitehorn beep(); 1597a1c0d96SNathan Whitehorn } 1607a1c0d96SNathan Whitehorn } 1617a1c0d96SNathan Whitehorn dlg_unregister_window(dialog); 1627a1c0d96SNathan Whitehorn return result; 1637a1c0d96SNathan Whitehorn } 1647a1c0d96SNathan Whitehorn 1654c8945a0SNathan Whitehorn int 1667a1c0d96SNathan Whitehorn dlg_progressbox(const char *title, 1677a1c0d96SNathan Whitehorn const char *cprompt, 1687a1c0d96SNathan Whitehorn int height, 1697a1c0d96SNathan Whitehorn int width, 1707a1c0d96SNathan Whitehorn int pauseopt, 1717a1c0d96SNathan Whitehorn FILE *fp) 1724c8945a0SNathan Whitehorn { 1734c8945a0SNathan Whitehorn int i; 1744c8945a0SNathan Whitehorn int x, y, thigh; 1754c8945a0SNathan Whitehorn WINDOW *dialog, *text; 1764c8945a0SNathan Whitehorn MY_OBJ *obj; 1774c8945a0SNathan Whitehorn char *prompt = dlg_strclone(cprompt); 1787a1c0d96SNathan Whitehorn int result; 1794c8945a0SNathan Whitehorn 1804c8945a0SNathan Whitehorn dlg_tab_correct_str(prompt); 1814c8945a0SNathan Whitehorn dlg_auto_size(title, prompt, &height, &width, MIN_HIGH, MIN_WIDE); 1824c8945a0SNathan Whitehorn dlg_print_size(height, width); 1834c8945a0SNathan Whitehorn dlg_ctl_size(height, width); 1844c8945a0SNathan Whitehorn 1854c8945a0SNathan Whitehorn x = dlg_box_x_ordinate(width); 1864c8945a0SNathan Whitehorn y = dlg_box_y_ordinate(height); 1874c8945a0SNathan Whitehorn thigh = height - (2 * MARGIN); 1884c8945a0SNathan Whitehorn 1894c8945a0SNathan Whitehorn dialog = dlg_new_window(height, width, y, x); 1904c8945a0SNathan Whitehorn 1914c8945a0SNathan Whitehorn dlg_draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr); 1924c8945a0SNathan Whitehorn dlg_draw_title(dialog, title); 193*682c9e0fSNathan Whitehorn dlg_draw_helpline(dialog, FALSE); 1944c8945a0SNathan Whitehorn 1954c8945a0SNathan Whitehorn if (*prompt != '\0') { 1964c8945a0SNathan Whitehorn int y2, x2; 1974c8945a0SNathan Whitehorn 1984c8945a0SNathan Whitehorn wattrset(dialog, dialog_attr); 1994c8945a0SNathan Whitehorn dlg_print_autowrap(dialog, prompt, height, width); 2004c8945a0SNathan Whitehorn getyx(dialog, y2, x2); 2014c8945a0SNathan Whitehorn ++y2; 2024c8945a0SNathan Whitehorn wmove(dialog, y2, MARGIN); 2034c8945a0SNathan Whitehorn for (i = 0; i < getmaxx(dialog) - 2 * MARGIN; i++) 2044c8945a0SNathan Whitehorn (void) waddch(dialog, dlg_boxchar(ACS_HLINE)); 2054c8945a0SNathan Whitehorn y += y2; 2064c8945a0SNathan Whitehorn thigh -= y2; 2074c8945a0SNathan Whitehorn } 2084c8945a0SNathan Whitehorn 2094c8945a0SNathan Whitehorn /* Create window for text region, used for scrolling text */ 2104c8945a0SNathan Whitehorn text = dlg_sub_window(dialog, 2114c8945a0SNathan Whitehorn thigh, 2124c8945a0SNathan Whitehorn width - (2 * MARGIN), 2134c8945a0SNathan Whitehorn y + MARGIN, 2144c8945a0SNathan Whitehorn x + MARGIN); 2154c8945a0SNathan Whitehorn 2164c8945a0SNathan Whitehorn (void) wrefresh(dialog); 2174c8945a0SNathan Whitehorn 2184c8945a0SNathan Whitehorn (void) wmove(dialog, thigh, (MARGIN + 1)); 2194c8945a0SNathan Whitehorn (void) wnoutrefresh(dialog); 2204c8945a0SNathan Whitehorn 2214c8945a0SNathan Whitehorn obj = dlg_calloc(MY_OBJ, 1); 2227a1c0d96SNathan Whitehorn assert_ptr(obj, "dlg_progressbox"); 2234c8945a0SNathan Whitehorn 2247a1c0d96SNathan Whitehorn obj->obj.input = fp; 2254c8945a0SNathan Whitehorn obj->obj.win = dialog; 2264c8945a0SNathan Whitehorn obj->text = text; 2274c8945a0SNathan Whitehorn 2284c8945a0SNathan Whitehorn dlg_attr_clear(text, thigh, getmaxx(text), dialog_attr); 2294c8945a0SNathan Whitehorn for (i = 0; get_line(obj); i++) { 2304c8945a0SNathan Whitehorn if (i < thigh) { 2314c8945a0SNathan Whitehorn print_line(obj, text, i, width - (2 * MARGIN)); 2324c8945a0SNathan Whitehorn } else { 2334c8945a0SNathan Whitehorn scrollok(text, TRUE); 2344c8945a0SNathan Whitehorn scroll(text); 2354c8945a0SNathan Whitehorn scrollok(text, FALSE); 2364c8945a0SNathan Whitehorn print_line(obj, text, thigh - 1, width - (2 * MARGIN)); 2374c8945a0SNathan Whitehorn } 2384c8945a0SNathan Whitehorn (void) wrefresh(text); 2394c8945a0SNathan Whitehorn if (obj->is_eof) 2404c8945a0SNathan Whitehorn break; 2414c8945a0SNathan Whitehorn } 2427a1c0d96SNathan Whitehorn 2437a1c0d96SNathan Whitehorn if (pauseopt) { 2447a1c0d96SNathan Whitehorn scrollok(text, TRUE); 2457a1c0d96SNathan Whitehorn wscrl(text, 1 + MARGIN); 2467a1c0d96SNathan Whitehorn (void) wrefresh(text); 2477a1c0d96SNathan Whitehorn result = pause_for_ok(dialog, height, width); 2487a1c0d96SNathan Whitehorn } else { 2497a1c0d96SNathan Whitehorn wrefresh(dialog); 2507a1c0d96SNathan Whitehorn result = DLG_EXIT_OK; 2517a1c0d96SNathan Whitehorn } 2527a1c0d96SNathan Whitehorn 2534c8945a0SNathan Whitehorn dlg_del_window(dialog); 2544c8945a0SNathan Whitehorn free(prompt); 2554c8945a0SNathan Whitehorn free(obj); 2564c8945a0SNathan Whitehorn 2574c8945a0SNathan Whitehorn return DLG_EXIT_OK; 2584c8945a0SNathan Whitehorn } 2597a1c0d96SNathan Whitehorn 2607a1c0d96SNathan Whitehorn /* 2617a1c0d96SNathan Whitehorn * Display text from a stdin in a scrolling window. 2627a1c0d96SNathan Whitehorn */ 2637a1c0d96SNathan Whitehorn int 2647a1c0d96SNathan Whitehorn dialog_progressbox(const char *title, const char *cprompt, int height, int width) 2657a1c0d96SNathan Whitehorn { 2667a1c0d96SNathan Whitehorn int result; 2677a1c0d96SNathan Whitehorn result = dlg_progressbox(title, 2687a1c0d96SNathan Whitehorn cprompt, 2697a1c0d96SNathan Whitehorn height, 2707a1c0d96SNathan Whitehorn width, 2717a1c0d96SNathan Whitehorn FALSE, 2727a1c0d96SNathan Whitehorn dialog_state.pipe_input); 2737a1c0d96SNathan Whitehorn dialog_state.pipe_input = 0; 2747a1c0d96SNathan Whitehorn return result; 2757a1c0d96SNathan Whitehorn } 276