13515Sache/*
23515Sache *  msgbox.c -- implements the message box and info box
33515Sache *
43515Sache *  AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
53515Sache *
63515Sache *  This program is free software; you can redistribute it and/or
73515Sache *  modify it under the terms of the GNU General Public License
83515Sache *  as published by the Free Software Foundation; either version 2
93515Sache *  of the License, or (at your option) any later version.
103515Sache *
113515Sache *  This program is distributed in the hope that it will be useful,
123515Sache *  but WITHOUT ANY WARRANTY; without even the implied warranty of
133515Sache *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
143515Sache *  GNU General Public License for more details.
153515Sache *
163515Sache *  You should have received a copy of the GNU General Public License
173515Sache *  along with this program; if not, write to the Free Software
183515Sache *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
193515Sache */
203515Sache
21114603Sobrien#include <sys/cdefs.h>
22114603Sobrien__FBSDID("$FreeBSD$");
233515Sache
243740Sache#include <dialog.h>
253515Sache#include "dialog.priv.h"
263515Sache
273515Sache
286458Sache/* local prototypes */
296458Sachestatic int 	getnlines(unsigned char *buf);
306458Sachestatic void	print_page(WINDOW *win, int height, int width, unsigned char *buf, int startline, int hscroll);
316458Sachestatic void 	print_perc(WINDOW *win, int y, int x, float p);
326458Sache
336458Sache
343515Sache/*
353515Sache * Display a message box. Program will pause and display an "OK" button
363515Sache * if the parameter 'pause' is non-zero.
373515Sache */
383515Sacheint dialog_msgbox(unsigned char *title, unsigned char *prompt, int height, int width, int pause)
393515Sache{
404527Sache  int i, j, x, y, key = 0;
413515Sache  WINDOW *dialog;
423515Sache
434527Sache  if (height < 0)
444527Sache	height = strheight(prompt)+2+2*(!!pause);
454527Sache  if (width < 0) {
464527Sache	i = strwidth(prompt);
476035Sache	j = ((title != NULL) ? strwidth(title) : 0);
484527Sache	width = MAX(i,j)+4;
494527Sache  }
506035Sache  if (pause)
516035Sache	width = MAX(width,10);
524527Sache
534658Sache  if (width > COLS)
544658Sache	width = COLS;
554658Sache  if (height > LINES)
564658Sache	height = LINES;
573515Sache  /* center dialog box on screen */
5813135Sjkh  x = DialogX ? DialogX : (COLS - width)/2;
5913135Sjkh  y = DialogY ? DialogY : (LINES - height)/2;
603515Sache
613515Sache#ifdef HAVE_NCURSES
623515Sache  if (use_shadow)
633515Sache    draw_shadow(stdscr, y, x, height, width);
643515Sache#endif
653515Sache  dialog = newwin(height, width, y, x);
664024Sache  if (dialog == NULL) {
674024Sache    endwin();
684024Sache    fprintf(stderr, "\nnewwin(%d,%d,%d,%d) failed, maybe wrong dims\n", height,width,y,x);
694024Sache    exit(1);
704024Sache  }
713515Sache  keypad(dialog, TRUE);
723515Sache
733515Sache  draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
743515Sache
753515Sache  if (title != NULL) {
763515Sache    wattrset(dialog, title_attr);
773515Sache    wmove(dialog, 0, (width - strlen(title))/2 - 1);
783515Sache    waddch(dialog, ' ');
793515Sache    waddstr(dialog, title);
803515Sache    waddch(dialog, ' ');
813515Sache  }
823515Sache  wattrset(dialog, dialog_attr);
833950Sache  wmove(dialog, 1, 2);
843950Sache  print_autowrap(dialog, prompt, height-1, width-2, width, 1, 2, TRUE, FALSE);
853515Sache
863515Sache  if (pause) {
873515Sache    wattrset(dialog, border_attr);
883515Sache    wmove(dialog, height-3, 0);
893515Sache    waddch(dialog, ACS_LTEE);
903515Sache    for (i = 0; i < width-2; i++)
913515Sache      waddch(dialog, ACS_HLINE);
923515Sache    wattrset(dialog, dialog_attr);
933515Sache    waddch(dialog, ACS_RTEE);
943515Sache    wmove(dialog, height-2, 1);
953515Sache    for (i = 0; i < width-2; i++)
963515Sache    waddch(dialog, ' ');
976458Sache    display_helpline(dialog, height-1, width);
9820359Sjkh    print_button(dialog, "  OK  ", height-2, width/2-6, TRUE);
993515Sache    wrefresh(dialog);
1003950Sache    while (key != ESC && key != '\n' && key != ' ' && key != '\r')
1013515Sache      key = wgetch(dialog);
1023950Sache    if (key == '\r')
1033950Sache      key = '\n';
1043515Sache  }
1053515Sache  else {
1063515Sache    key = '\n';
1073515Sache    wrefresh(dialog);
1083515Sache  }
1093515Sache
1103515Sache  delwin(dialog);
1113515Sache  return (key == ESC ? -1 : 0);
1123515Sache}
1133515Sache/* End of dialog_msgbox() */
1146458Sache
1156458Sacheint
1166458Sachedialog_mesgbox(unsigned char *title, unsigned char *prompt, int height, int width)
1176458Sache/*
1186458Sache * Desc: basically the same as dialog_msgbox, but ... can use PGUP, PGDN and
1196458Sache *	 arrowkeys to move around the text and pause is always enabled
1206458Sache */
1216458Sache{
1226458Sache    int 	i, j, x, y, key=0;
1236458Sache    int		theight, startline, hscroll, max_lines;
1246458Sache    WINDOW 	*dialog;
1256458Sache
1266458Sache    if (height < 0)
1276674Sache	height = strheight(prompt)+2+2;
1286458Sache    if (width < 0) {
1296458Sache	i = strwidth(prompt);
1306674Sache	j = ((title != NULL) ? strwidth(title) : 0);
1316458Sache	width = MAX(i,j)+4;
1326458Sache    }
1336674Sache    width = MAX(width,10);
1346458Sache
1356458Sache    if (width > COLS)
1366458Sache	width = COLS;
1376458Sache    if (height > LINES)
1386458Sache	height = LINES;
1396458Sache    /* center dialog box on screen */
1406458Sache    x = (COLS - width)/2;
1416458Sache    y = (LINES - height)/2;
1426458Sache
1436458Sache#ifdef HAVE_NCURSES
1446458Sache    if (use_shadow)
1456458Sache	draw_shadow(stdscr, y, x, height, width);
1466458Sache#endif
1476458Sache    dialog = newwin(height, width, y, x);
1486458Sache    if (dialog == NULL) {
1496458Sache	endwin();
1506458Sache	fprintf(stderr, "\nnewwin(%d,%d,%d,%d) failed, maybe wrong dims\n", height,width,y,x);
1516458Sache	exit(1);
1526458Sache    }
1536458Sache    keypad(dialog, TRUE);
1546458Sache
1556458Sache    draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
1566458Sache
1576458Sache    if (title != NULL) {
1586458Sache	wattrset(dialog, title_attr);
1596458Sache	wmove(dialog, 0, (width - strlen(title))/2 - 1);
1606458Sache	waddch(dialog, ' ');
1616458Sache	waddstr(dialog, title);
1626458Sache	waddch(dialog, ' ');
1636458Sache    }
1646458Sache
1656674Sache    wattrset(dialog, border_attr);
1666458Sache    wmove(dialog, height-3, 0);
1676458Sache    waddch(dialog, ACS_LTEE);
1686458Sache    for (i = 0; i < width-2; i++)
1696458Sache      waddch(dialog, ACS_HLINE);
1706458Sache    wattrset(dialog, dialog_attr);
1716458Sache    waddch(dialog, ACS_RTEE);
1726458Sache    wmove(dialog, height-2, 1);
1736458Sache    for (i = 0; i < width-2; i++)
1746458Sache    waddch(dialog, ' ');
1756458Sache    display_helpline(dialog, height-1, width);
17620359Sjkh    print_button(dialog, "  OK  ", height-2, width/2-6, TRUE);
1776458Sache    wattrset(dialog, dialog_attr);
1786458Sache
1796458Sache    theight = height - 4;
1806458Sache    startline = 0;
1816458Sache    hscroll = 0;
1826458Sache    max_lines = getnlines(prompt);
1836458Sache    print_page(dialog, theight, width, prompt, startline, hscroll);
1846458Sache    print_perc(dialog, height-3, width-9, (float) (startline+theight)/max_lines);
18524389Sjkh    wmove(dialog, height-2, width/2-3);
1866458Sache    wrefresh(dialog);
18781331Seric    while ((key != ESC) && (key != '\n') && (key != '\r') && (key != ' ')) {
1886458Sache	key = wgetch(dialog);
1896458Sache	switch(key) {
1906458Sache	case KEY_HOME:
1916458Sache	    startline=0;
1926458Sache	    hscroll=0;
1936458Sache	    break;
1946458Sache	case KEY_END:
1956458Sache	    startline = max_lines - theight;
1966458Sache	    if (startline < 0) startline = 0;
1976458Sache	    break;
19821697Sjkh	case '\020':	/* ^P */
1996458Sache	case KEY_UP:
2006458Sache	    if (startline > 0) startline--;
2016458Sache	    break;
20221697Sjkh	case '\016':	/* ^N */
2036458Sache	case KEY_DOWN:
2046458Sache	    if (startline < max_lines - theight) startline++;
2056458Sache	    break;
2066458Sache	case KEY_RIGHT:
2077959Sache	    hscroll+=5;
2086458Sache	    break;
2096458Sache	case KEY_LEFT:
2107959Sache	    if (hscroll > 0) hscroll-=5;
2117959Sache	    if (hscroll < 0) hscroll =0;
2126458Sache	    break;
2136458Sache	case KEY_PPAGE:
2146458Sache	    if (startline - height > 0) {
2156458Sache		startline -= theight;
2166458Sache	    } else {
2176458Sache		startline = 0;
2186458Sache	    }
2196458Sache	    break;
2206458Sache	case KEY_NPAGE:
2216458Sache	    if (startline + theight < max_lines - theight) {
2226458Sache		startline += theight;
2236458Sache	    } else {
2246458Sache		startline = max_lines - theight;
2256458Sache		if (startline < 0) startline = 0;
2266458Sache	    }
2276458Sache	    break;
2286458Sache	case KEY_F(1):
2296458Sache	case '?':
2306458Sache	    display_helpfile();
2316458Sache	    break;
2326458Sache	}
2338858Srgrimes	print_page(dialog, theight, width, prompt, startline, hscroll);
2346458Sache	print_perc(dialog, height-3, width-9, (float) (startline+theight)/max_lines);
23524389Sjkh	wmove(dialog, height-2, width/2-3);
2366458Sache	wrefresh(dialog);
2376458Sache    }
2386458Sache
2396458Sache    delwin(dialog);
2406458Sache    return (key == ESC ? -1 : 0);
2416458Sache
2426458Sache} /* dialog_mesgbox() */
2436458Sache
2446458Sachestatic void
2456458Sacheprint_perc(WINDOW *win, int y, int x, float p)
2466458Sache/*
2476458Sache * Desc: print p as a percentage at the coordinates (y,x)
2486458Sache */
2496458Sache{
2506458Sache    char	ps[10];
2516458Sache
2526458Sache    if (p>1.0) p=1.0;
2536458Sache    sprintf(ps, "(%3d%%)", (int) (p*100));
2546458Sache    wmove(win, y, x);
2556458Sache    waddstr(win, ps);
2566458Sache
2576458Sache    return;
2586458Sache} /* print_perc() */
2596458Sache
2606458Sachestatic int
2616458Sachegetnlines(unsigned char *buf)
2626458Sache/*
2636458Sache * Desc: count the # of lines in <buf>
2646458Sache */
2656458Sache{
2666458Sache    int i = 0;
2676458Sache
2687959Sache    if (*buf)
2697959Sache	i++;
2706458Sache    while (*buf) {
2717959Sache	if (*buf == '\n' || *buf == '\r')
2726458Sache	    i++;
2736458Sache	buf++;
2746458Sache    }
2756458Sache    return(i);
2766458Sache} /* getlines() */
2776458Sache
2786458Sache
2796458Sacheunsigned char *
2806458Sachegetline(unsigned char *buf, int n)
2816458Sache/*
2826458Sache * Desc: return a pointer to the n'th line in <buf> or NULL if its
2836458Sache *	 not there
2846458Sache */
2856458Sache{
2866458Sache    int i;
2876458Sache
2886458Sache    if (n<0) {
2896458Sache	return(NULL);
2906458Sache    }
2918858Srgrimes
2926458Sache    i=0;
2936458Sache    while (*buf && i<n) {
2946458Sache	if (*buf == '\n' || *buf == '\r') {
2956458Sache	    i++;
2966458Sache	}
2976458Sache	buf++;
2986458Sache    }
2996458Sache    if (i<n) {
3006458Sache	return(NULL);
3016458Sache    } else {
3026458Sache	return(buf);
3036458Sache    }
3046458Sache} /* getline() */
3056458Sache
3066458Sachestatic void
3076458Sacheprint_page(WINDOW *win, int height, int width, unsigned char *buf, int startline, int hscroll)
3086458Sache/*
3096458Sache * Desc: Print a page of text in the current window, starting at line <startline>
3106458Sache *	 with a <horizontal> scroll of hscroll from buffer <buf>
3116458Sache */
3126458Sache{
3136458Sache    int i, j;
3146458Sache    unsigned char *b;
3156458Sache
3166458Sache    b = getline(buf, startline);
3176458Sache    for (i=0; i<height; i++) {
3186458Sache	/* clear line */
3196458Sache	wmove(win, 1+i, 1);
3206458Sache	for (j=0; j<width-2; j++) waddnstr(win, " ", 1);
3216458Sache	wmove(win, 1+i, 1);
3228858Srgrimes	j = 0;
3236458Sache	/* scroll to the right */
3246458Sache	while (*b && (*b != '\n') && (*b != '\r') && (j<hscroll)) {
3256458Sache	    b++;
3266458Sache	    j++;
3276458Sache	}
3286458Sache	/* print new line */
3296458Sache	j = 0;
3306458Sache	while (*b && (*b != '\n') && (*b != '\r') && (j<width-2)) {
3316458Sache	    waddnstr(win, b, 1);
3326458Sache	    if (*b != '\t') {	/* check for tabs */
3336458Sache		j++;
3346458Sache	    } else {
3356458Sache		j = ((int) (j+1)/8 + 1) * 8 - 1;
3366458Sache	    }
3376458Sache	    b++;
3386458Sache	}
3396458Sache	while (*b && (*b != '\n') && (*b != '\r')) b++;
3406458Sache	if (*b) b++;	/* skip over '\n', if it exists */
3416458Sache    }
3426458Sache} /* print_page() */
3438858Srgrimes
3448858Srgrimes
3458858Srgrimes
3468858Srgrimes
347