1217309Snwhitehorn/* 2251843Sbapt * $Id: mixedgauge.c,v 1.30 2012/11/18 16:30:20 tom Exp $ 3217309Snwhitehorn * 4217309Snwhitehorn * mixedgauge.c -- implements the mixedgauge dialog 5217309Snwhitehorn * 6251843Sbapt * Copyright 2007-2011,2012 Thomas E. Dickey 7217309Snwhitehorn * 8217309Snwhitehorn * This program is free software; you can redistribute it and/or modify 9217309Snwhitehorn * it under the terms of the GNU Lesser General Public License, version 2.1 10217309Snwhitehorn * as published by the Free Software Foundation. 11217309Snwhitehorn * 12217309Snwhitehorn * This program is distributed in the hope that it will be useful, but 13217309Snwhitehorn * WITHOUT ANY WARRANTY; without even the implied warranty of 14217309Snwhitehorn * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15217309Snwhitehorn * Lesser General Public License for more details. 16217309Snwhitehorn * 17217309Snwhitehorn * You should have received a copy of the GNU Lesser General Public 18217309Snwhitehorn * License along with this program; if not, write to 19217309Snwhitehorn * Free Software Foundation, Inc. 20217309Snwhitehorn * 51 Franklin St., Fifth Floor 21217309Snwhitehorn * Boston, MA 02110, USA. 22217309Snwhitehorn * 23217309Snwhitehorn * This is inspired by a patch from Kiran Cherupally 24217309Snwhitehorn * (but different interface design). 25217309Snwhitehorn */ 26217309Snwhitehorn 27217309Snwhitehorn#include <dialog.h> 28217309Snwhitehorn 29217309Snwhitehorn#define LLEN(n) ((n) * MIXEDGAUGE_TAGS) 30217309Snwhitehorn#define ItemData(i) &items[LLEN(i)] 31217309Snwhitehorn#define ItemName(i) items[LLEN(i)] 32217309Snwhitehorn#define ItemText(i) items[LLEN(i) + 1] 33217309Snwhitehorn 34217309Snwhitehorn#define MIN_HIGH (4) 35217309Snwhitehorn#define MIN_WIDE (10 + 2 * (2 + MARGIN)) 36217309Snwhitehorn 37217309Snwhitehorntypedef struct { 38217309Snwhitehorn WINDOW *dialog; 39217309Snwhitehorn WINDOW *caption; 40217309Snwhitehorn const char *title; 41217309Snwhitehorn char *prompt; 42217309Snwhitehorn int height, old_height, min_height; 43217309Snwhitehorn int width, old_width, min_width; 44217309Snwhitehorn int len_name, len_text; 45217309Snwhitehorn int item_no; 46217309Snwhitehorn DIALOG_LISTITEM *list; 47217309Snwhitehorn} DIALOG_MIXEDGAUGE; 48217309Snwhitehorn 49217309Snwhitehornstatic const char * 50217309Snwhitehornstatus_string(char *given, char **freeMe) 51217309Snwhitehorn{ 52217309Snwhitehorn const char *result; 53217309Snwhitehorn 54217309Snwhitehorn *freeMe = 0; 55217309Snwhitehorn if (isdigit(UCH(*given))) { 56217309Snwhitehorn switch (*given) { 57217309Snwhitehorn case '0': 58217309Snwhitehorn result = _("Succeeded"); 59217309Snwhitehorn break; 60217309Snwhitehorn case '1': 61217309Snwhitehorn result = _("Failed"); 62217309Snwhitehorn break; 63217309Snwhitehorn case '2': 64217309Snwhitehorn result = _("Passed"); 65217309Snwhitehorn break; 66217309Snwhitehorn case '3': 67217309Snwhitehorn result = _("Completed"); 68217309Snwhitehorn break; 69217309Snwhitehorn case '4': 70217309Snwhitehorn result = _("Checked"); 71217309Snwhitehorn break; 72217309Snwhitehorn case '5': 73217309Snwhitehorn result = _("Done"); 74217309Snwhitehorn break; 75217309Snwhitehorn case '6': 76217309Snwhitehorn result = _("Skipped"); 77217309Snwhitehorn break; 78217309Snwhitehorn case '7': 79217309Snwhitehorn result = _("In Progress"); 80217309Snwhitehorn break; 81217309Snwhitehorn case '8': 82217309Snwhitehorn result = ""; 83217309Snwhitehorn break; 84217309Snwhitehorn case '9': 85217309Snwhitehorn result = _("N/A"); 86217309Snwhitehorn break; 87217309Snwhitehorn default: 88217309Snwhitehorn result = "?"; 89217309Snwhitehorn break; 90217309Snwhitehorn } 91217309Snwhitehorn } else if (*given == '-') { 92220749Snwhitehorn size_t need = strlen(++given); 93217309Snwhitehorn char *temp = dlg_malloc(char, need); 94217309Snwhitehorn *freeMe = temp; 95217309Snwhitehorn sprintf(temp, "%3s%%", given); 96217309Snwhitehorn result = temp; 97217309Snwhitehorn } else if (!isspace(UCH(*given))) { 98217309Snwhitehorn result = given; 99217309Snwhitehorn } else { 100217309Snwhitehorn result = 0; 101217309Snwhitehorn } 102217309Snwhitehorn return result; 103217309Snwhitehorn} 104217309Snwhitehorn 105217309Snwhitehorn/* This function displays status messages */ 106217309Snwhitehornstatic void 107217309Snwhitehornmyprint_status(DIALOG_MIXEDGAUGE * dlg) 108217309Snwhitehorn{ 109217309Snwhitehorn WINDOW *win = dlg->dialog; 110217309Snwhitehorn int limit_y = dlg->height; 111217309Snwhitehorn int limit_x = dlg->width; 112217309Snwhitehorn 113217309Snwhitehorn int y = MARGIN; 114217309Snwhitehorn int item; 115217309Snwhitehorn int cells = dlg->len_text - 2; 116217309Snwhitehorn int lm = limit_x - dlg->len_text - 1; 117217309Snwhitehorn int bm = limit_y; /* bottom margin */ 118217309Snwhitehorn int last_y = 0, last_x = 0; 119217309Snwhitehorn int j, xxx; 120217309Snwhitehorn float percent; 121217309Snwhitehorn const char *status = ""; 122217309Snwhitehorn char *freeMe = 0; 123217309Snwhitehorn 124251843Sbapt bm -= (2 * MARGIN); 125251843Sbapt getyx(win, last_y, last_x); 126217309Snwhitehorn for (item = 0; item < dlg->item_no; ++item) { 127217309Snwhitehorn chtype attr = A_NORMAL; 128217309Snwhitehorn 129217309Snwhitehorn y = item + MARGIN + 1; 130217309Snwhitehorn if (y > bm) 131217309Snwhitehorn break; 132217309Snwhitehorn 133217309Snwhitehorn status = status_string(dlg->list[item].text, &freeMe); 134217309Snwhitehorn if (status == 0 || *status == 0) 135217309Snwhitehorn continue; 136217309Snwhitehorn 137217309Snwhitehorn (void) wmove(win, y, 2 * MARGIN); 138217309Snwhitehorn dlg_print_text(win, dlg->list[item].name, lm, &attr); 139217309Snwhitehorn 140217309Snwhitehorn (void) wmove(win, y, lm); 141217309Snwhitehorn (void) waddch(win, '['); 142217309Snwhitehorn (void) wmove(win, y, lm + (cells - (int) strlen(status)) / 2); 143217309Snwhitehorn if (freeMe) { 144217309Snwhitehorn (void) wmove(win, y, lm + 1); 145251843Sbapt (void) wattrset(win, title_attr); 146217309Snwhitehorn for (j = 0; j < cells; j++) 147217309Snwhitehorn (void) waddch(win, ' '); 148217309Snwhitehorn 149217309Snwhitehorn (void) wmove(win, y, lm + (cells - (int) strlen(status)) / 2); 150217309Snwhitehorn (void) waddstr(win, status); 151217309Snwhitehorn 152217309Snwhitehorn if ((title_attr & A_REVERSE) != 0) { 153217309Snwhitehorn wattroff(win, A_REVERSE); 154217309Snwhitehorn } else { 155251843Sbapt (void) wattrset(win, A_REVERSE); 156217309Snwhitehorn } 157217309Snwhitehorn (void) wmove(win, y, lm + 1); 158217309Snwhitehorn 159217309Snwhitehorn if (sscanf(status, "%f%%", &percent) != 1) 160217309Snwhitehorn percent = 0.0; 161217309Snwhitehorn xxx = (int) ((cells * (percent + 0.5)) / 100.0); 162217309Snwhitehorn for (j = 0; j < xxx; j++) { 163217309Snwhitehorn chtype ch1 = winch(win); 164217309Snwhitehorn if (title_attr & A_REVERSE) { 165217309Snwhitehorn ch1 &= ~A_REVERSE; 166217309Snwhitehorn } 167217309Snwhitehorn (void) waddch(win, ch1); 168217309Snwhitehorn } 169217309Snwhitehorn free(freeMe); 170217309Snwhitehorn 171217309Snwhitehorn } else { 172217309Snwhitehorn (void) wmove(win, y, lm + (cells - (int) strlen(status)) / 2); 173217309Snwhitehorn (void) waddstr(win, status); 174217309Snwhitehorn } 175217309Snwhitehorn (void) wmove(win, y, limit_x - 3); 176217309Snwhitehorn (void) waddch(win, ']'); 177217309Snwhitehorn (void) wnoutrefresh(win); 178217309Snwhitehorn } 179251843Sbapt if (win != 0) 180251843Sbapt wmove(win, last_y, last_x); 181217309Snwhitehorn} 182217309Snwhitehorn 183217309Snwhitehornstatic void 184217309Snwhitehornmydraw_mixed_box(WINDOW *win, int y, int x, int height, int width, 185217309Snwhitehorn chtype boxchar, chtype borderchar) 186217309Snwhitehorn{ 187217309Snwhitehorn dlg_draw_box(win, y, x, height, width, boxchar, borderchar); 188217309Snwhitehorn { 189217309Snwhitehorn chtype attr = A_NORMAL; 190220749Snwhitehorn const char *message = _("Overall Progress"); 191220749Snwhitehorn chtype save2 = dlg_get_attrs(win); 192251843Sbapt (void) wattrset(win, title_attr); 193217309Snwhitehorn (void) wmove(win, y, x + 2); 194217309Snwhitehorn dlg_print_text(win, message, width, &attr); 195251843Sbapt (void) wattrset(win, save2); 196217309Snwhitehorn } 197217309Snwhitehorn} 198217309Snwhitehorn 199217309Snwhitehornstatic char * 200217309Snwhitehornclean_copy(const char *string) 201217309Snwhitehorn{ 202217309Snwhitehorn char *result = dlg_strclone(string); 203217309Snwhitehorn 204217309Snwhitehorn dlg_trim_string(result); 205217309Snwhitehorn dlg_tab_correct_str(result); 206217309Snwhitehorn return result; 207217309Snwhitehorn} 208217309Snwhitehorn 209217309Snwhitehorn/* 210217309Snwhitehorn * Update mixed-gauge dialog (may be from pipe, may be via direct calls). 211217309Snwhitehorn */ 212217309Snwhitehornstatic void 213217309Snwhitehorndlg_update_mixedgauge(DIALOG_MIXEDGAUGE * dlg, int percent) 214217309Snwhitehorn{ 215217309Snwhitehorn int i, x; 216217309Snwhitehorn 217217309Snwhitehorn /* 218217309Snwhitehorn * Clear the area for the progress bar by filling it with spaces 219217309Snwhitehorn * in the title-attribute, and write the percentage with that 220217309Snwhitehorn * attribute. 221217309Snwhitehorn */ 222217309Snwhitehorn (void) wmove(dlg->dialog, dlg->height - 3, 4); 223251843Sbapt (void) wattrset(dlg->dialog, gauge_attr); 224217309Snwhitehorn 225217309Snwhitehorn for (i = 0; i < (dlg->width - 2 * (3 + MARGIN)); i++) 226217309Snwhitehorn (void) waddch(dlg->dialog, ' '); 227217309Snwhitehorn 228217309Snwhitehorn (void) wmove(dlg->dialog, dlg->height - 3, (dlg->width / 2) - 2); 229217309Snwhitehorn (void) wprintw(dlg->dialog, "%3d%%", percent); 230217309Snwhitehorn 231217309Snwhitehorn /* 232217309Snwhitehorn * Now draw a bar in reverse, relative to the background. 233217309Snwhitehorn * The window attribute was useful for painting the background, 234217309Snwhitehorn * but requires some tweaks to reverse it. 235217309Snwhitehorn */ 236217309Snwhitehorn x = (percent * (dlg->width - 2 * (3 + MARGIN))) / 100; 237217309Snwhitehorn if ((title_attr & A_REVERSE) != 0) { 238217309Snwhitehorn wattroff(dlg->dialog, A_REVERSE); 239217309Snwhitehorn } else { 240251843Sbapt (void) wattrset(dlg->dialog, A_REVERSE); 241217309Snwhitehorn } 242217309Snwhitehorn (void) wmove(dlg->dialog, dlg->height - 3, 4); 243217309Snwhitehorn for (i = 0; i < x; i++) { 244217309Snwhitehorn chtype ch = winch(dlg->dialog); 245217309Snwhitehorn if (title_attr & A_REVERSE) { 246217309Snwhitehorn ch &= ~A_REVERSE; 247217309Snwhitehorn } 248217309Snwhitehorn (void) waddch(dlg->dialog, ch); 249217309Snwhitehorn } 250217309Snwhitehorn myprint_status(dlg); 251251843Sbapt dlg_trace_win(dlg->dialog); 252217309Snwhitehorn} 253217309Snwhitehorn 254217309Snwhitehorn/* 255217309Snwhitehorn * Setup dialog. 256217309Snwhitehorn */ 257217309Snwhitehornstatic void 258217309Snwhitehorndlg_begin_mixedgauge(DIALOG_MIXEDGAUGE * dlg, 259217309Snwhitehorn int *began, 260217309Snwhitehorn const char *aTitle, 261217309Snwhitehorn const char *aPrompt, 262217309Snwhitehorn int aHeight, 263217309Snwhitehorn int aWidth, 264217309Snwhitehorn int aItemNo, 265217309Snwhitehorn char **items) 266217309Snwhitehorn{ 267217309Snwhitehorn int n, y, x; 268217309Snwhitehorn 269217309Snwhitehorn if (!*began) { 270217309Snwhitehorn curs_set(0); 271217309Snwhitehorn 272217309Snwhitehorn memset(dlg, 0, sizeof(*dlg)); 273217309Snwhitehorn dlg->title = aTitle; 274217309Snwhitehorn dlg->prompt = clean_copy(aPrompt); 275217309Snwhitehorn dlg->height = dlg->old_height = aHeight; 276217309Snwhitehorn dlg->width = dlg->old_width = aWidth; 277217309Snwhitehorn dlg->item_no = aItemNo; 278217309Snwhitehorn 279217309Snwhitehorn dlg->list = dlg_calloc(DIALOG_LISTITEM, (size_t) aItemNo); 280217309Snwhitehorn assert_ptr(dlg->list, "dialog_mixedgauge"); 281217309Snwhitehorn 282217309Snwhitehorn dlg->len_name = 0; 283217309Snwhitehorn dlg->len_text = 15; 284217309Snwhitehorn 285217309Snwhitehorn for (n = 0; n < aItemNo; ++n) { 286217309Snwhitehorn int thisWidth = (int) strlen(ItemName(n)); 287217309Snwhitehorn if (dlg->len_name < thisWidth) 288217309Snwhitehorn dlg->len_name = thisWidth; 289217309Snwhitehorn dlg->list[n].name = ItemName(n); 290217309Snwhitehorn dlg->list[n].text = ItemText(n); 291217309Snwhitehorn } 292217309Snwhitehorn 293217309Snwhitehorn dlg->min_height = MIN_HIGH + aItemNo; 294217309Snwhitehorn dlg->min_width = MIN_WIDE + dlg->len_name + GUTTER + dlg->len_text; 295217309Snwhitehorn 296217309Snwhitehorn if (dlg->prompt != 0 && *(dlg->prompt) != 0) 297217309Snwhitehorn dlg->min_height += (2 * MARGIN); 298217309Snwhitehorn#ifdef KEY_RESIZE 299217309Snwhitehorn nodelay(stdscr, TRUE); 300217309Snwhitehorn#endif 301217309Snwhitehorn } 302217309Snwhitehorn#ifdef KEY_RESIZE 303217309Snwhitehorn else { 304217309Snwhitehorn dlg_del_window(dlg->dialog); 305217309Snwhitehorn dlg->height = dlg->old_height; 306217309Snwhitehorn dlg->width = dlg->old_width; 307217309Snwhitehorn } 308217309Snwhitehorn#endif 309217309Snwhitehorn 310217309Snwhitehorn dlg_auto_size(dlg->title, dlg->prompt, 311217309Snwhitehorn &(dlg->height), 312217309Snwhitehorn &(dlg->width), 313217309Snwhitehorn dlg->min_height, 314217309Snwhitehorn dlg->min_width); 315217309Snwhitehorn dlg_print_size(dlg->height, dlg->width); 316217309Snwhitehorn dlg_ctl_size(dlg->height, dlg->width); 317217309Snwhitehorn 318217309Snwhitehorn /* center dialog box on screen */ 319217309Snwhitehorn x = dlg_box_x_ordinate(dlg->width); 320217309Snwhitehorn y = dlg_box_y_ordinate(dlg->height); 321217309Snwhitehorn 322217309Snwhitehorn dlg->dialog = dlg_new_window(dlg->height, dlg->width, y, x); 323217309Snwhitehorn 324217309Snwhitehorn (void) werase(dlg->dialog); 325251843Sbapt dlg_draw_box2(dlg->dialog, 326251843Sbapt 0, 0, 327251843Sbapt dlg->height, 328251843Sbapt dlg->width, 329251843Sbapt dialog_attr, border_attr, border2_attr); 330217309Snwhitehorn 331217309Snwhitehorn dlg_draw_title(dlg->dialog, dlg->title); 332224014Snwhitehorn dlg_draw_helpline(dlg->dialog, FALSE); 333217309Snwhitehorn 334217309Snwhitehorn if ((dlg->prompt != 0 && *(dlg->prompt) != 0) 335217309Snwhitehorn && wmove(dlg->dialog, dlg->item_no, 0) != ERR) { 336217309Snwhitehorn dlg->caption = dlg_sub_window(dlg->dialog, 337217309Snwhitehorn dlg->height - dlg->item_no - (2 * MARGIN), 338217309Snwhitehorn dlg->width, 339217309Snwhitehorn y + dlg->item_no + (2 * MARGIN), 340217309Snwhitehorn x); 341251843Sbapt (void) wattrset(dlg->caption, dialog_attr); 342217309Snwhitehorn dlg_print_autowrap(dlg->caption, dlg->prompt, dlg->height, dlg->width); 343217309Snwhitehorn } 344217309Snwhitehorn 345217309Snwhitehorn mydraw_mixed_box(dlg->dialog, 346217309Snwhitehorn dlg->height - 4, 347217309Snwhitehorn 2 + MARGIN, 348217309Snwhitehorn 2 + MARGIN, 349217309Snwhitehorn dlg->width - 2 * (2 + MARGIN), 350217309Snwhitehorn dialog_attr, 351217309Snwhitehorn border_attr); 352217309Snwhitehorn 353217309Snwhitehorn *began += 1; 354217309Snwhitehorn} 355217309Snwhitehorn 356217309Snwhitehorn/* 357217309Snwhitehorn * Discard the mixed-gauge dialog. 358217309Snwhitehorn */ 359217309Snwhitehornstatic int 360217309Snwhitehorndlg_finish_mixedgauge(DIALOG_MIXEDGAUGE * dlg, int status) 361217309Snwhitehorn{ 362217309Snwhitehorn (void) wrefresh(dlg->dialog); 363217309Snwhitehorn#ifdef KEY_RESIZE 364217309Snwhitehorn nodelay(stdscr, FALSE); 365217309Snwhitehorn#endif 366217309Snwhitehorn curs_set(1); 367217309Snwhitehorn dlg_del_window(dlg->dialog); 368217309Snwhitehorn return status; 369217309Snwhitehorn} 370217309Snwhitehorn 371217309Snwhitehorn/* 372217309Snwhitehorn * Setup dialog, read mixed-gauge data from pipe. 373217309Snwhitehorn */ 374217309Snwhitehornint 375217309Snwhitehorndialog_mixedgauge(const char *title, 376217309Snwhitehorn const char *cprompt, 377217309Snwhitehorn int height, 378217309Snwhitehorn int width, 379217309Snwhitehorn int percent, 380217309Snwhitehorn int item_no, 381217309Snwhitehorn char **items) 382217309Snwhitehorn{ 383217309Snwhitehorn DIALOG_MIXEDGAUGE dlg; 384217309Snwhitehorn int began = 0; 385217309Snwhitehorn 386217309Snwhitehorn dlg_begin_mixedgauge(&dlg, &began, title, cprompt, height, 387217309Snwhitehorn width, item_no, items); 388217309Snwhitehorn 389217309Snwhitehorn dlg_update_mixedgauge(&dlg, percent); 390217309Snwhitehorn 391217309Snwhitehorn return dlg_finish_mixedgauge(&dlg, DLG_EXIT_OK); 392217309Snwhitehorn} 393