1/*
2 *  $Id: yesno.c,v 1.51 2011/06/27 08:20:57 tom Exp $
3 *
4 *  yesno.c -- implements the yes/no box
5 *
6 *  Copyright 1999-2010,2011	Thomas E. Dickey
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, version 2.1
10 *  as published by the Free Software Foundation.
11 *
12 *  This program is distributed in the hope that it will be useful, but
13 *  WITHOUT ANY WARRANTY; without even the implied warranty of
14 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 *  Lesser General Public License for more details.
16 *
17 *  You should have received a copy of the GNU Lesser General Public
18 *  License along with this program; if not, write to
19 *	Free Software Foundation, Inc.
20 *	51 Franklin St., Fifth Floor
21 *	Boston, MA 02110, USA.
22 *
23 *  An earlier version of this program lists as authors
24 *	Savio Lam (lam836@cs.cuhk.hk)
25 */
26
27#include <dialog.h>
28#include <dlg_keys.h>
29
30/*
31 * Display a dialog box with two buttons - Yes and No.
32 */
33int
34dialog_yesno(const char *title, const char *cprompt, int height, int width)
35{
36    /* *INDENT-OFF* */
37    static DLG_KEYS_BINDING binding[] = {
38	HELPKEY_BINDINGS,
39	ENTERKEY_BINDINGS,
40	DLG_KEYS_DATA( DLGK_ENTER,	' ' ),
41	DLG_KEYS_DATA( DLGK_FIELD_NEXT,	KEY_DOWN ),
42	DLG_KEYS_DATA( DLGK_FIELD_NEXT, KEY_RIGHT ),
43	DLG_KEYS_DATA( DLGK_FIELD_NEXT, TAB ),
44	DLG_KEYS_DATA( DLGK_FIELD_PREV,	KEY_UP ),
45	DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_BTAB ),
46	DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_LEFT ),
47	SCROLLKEY_BINDINGS,
48	END_KEYS_BINDING
49    };
50    /* *INDENT-ON* */
51
52    int x, y;
53    int key = 0, fkey;
54    int code;
55    int button = dlg_defaultno_button();
56    WINDOW *dialog = 0;
57    int result = DLG_EXIT_UNKNOWN;
58    char *prompt = dlg_strclone(cprompt);
59    const char **buttons = dlg_yes_labels();
60    int min_width = 25;
61    bool show = TRUE;
62    int page, last = 0, offset = 0;
63
64#ifdef KEY_RESIZE
65    int req_high = height;
66    int req_wide = width;
67  restart:
68#endif
69
70    dlg_tab_correct_str(prompt);
71    dlg_button_layout(buttons, &min_width);
72    dlg_auto_size(title, prompt, &height, &width, 2, min_width);
73    dlg_print_size(height, width);
74    dlg_ctl_size(height, width);
75
76    x = dlg_box_x_ordinate(width);
77    y = dlg_box_y_ordinate(height);
78
79#ifdef KEY_RESIZE
80    if (dialog != 0)
81	dlg_move_window(dialog, height, width, y, x);
82    else
83#endif
84    {
85	dialog = dlg_new_window(height, width, y, x);
86	dlg_register_window(dialog, "yesno", binding);
87	dlg_register_buttons(dialog, "yesno", buttons);
88    }
89
90    dlg_draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr);
91    dlg_draw_bottom_box(dialog);
92    dlg_draw_title(dialog, title);
93    dlg_draw_helpline(dialog, FALSE);
94
95    wattrset(dialog, dialog_attr);
96
97    page = height - (1 + 3 * MARGIN);
98    dlg_draw_buttons(dialog,
99		     height - 2 * MARGIN, 0,
100		     buttons, button, FALSE, width);
101
102    while (result == DLG_EXIT_UNKNOWN) {
103	if (show) {
104	    last = dlg_print_scrolled(dialog, prompt, offset,
105				      page, width, TRUE);
106	    show = FALSE;
107	}
108	key = dlg_mouse_wgetch(dialog, &fkey);
109	if (dlg_result_key(key, fkey, &result))
110	    break;
111	if ((code = dlg_char_to_button(key, buttons)) >= 0) {
112	    result = dlg_ok_buttoncode(code);
113	    break;
114	}
115	/* handle function keys */
116	if (fkey) {
117	    switch (key) {
118	    case DLGK_FIELD_NEXT:
119		button = dlg_next_button(buttons, button);
120		if (button < 0)
121		    button = 0;
122		dlg_draw_buttons(dialog,
123				 height - 2, 0,
124				 buttons, button,
125				 FALSE, width);
126		break;
127	    case DLGK_FIELD_PREV:
128		button = dlg_prev_button(buttons, button);
129		if (button < 0)
130		    button = 0;
131		dlg_draw_buttons(dialog,
132				 height - 2, 0,
133				 buttons, button,
134				 FALSE, width);
135		break;
136	    case DLGK_ENTER:
137		result = dlg_yes_buttoncode(button);
138		break;
139#ifdef KEY_RESIZE
140	    case KEY_RESIZE:
141		dlg_clear();
142		height = req_high;
143		width = req_wide;
144		goto restart;
145#endif
146	    default:
147		if (is_DLGK_MOUSE(key)) {
148		    result = dlg_yes_buttoncode(key - M_EVENT);
149		    if (result < 0)
150			result = DLG_EXIT_OK;
151		} else if (dlg_check_scrolled(key, last, page,
152					      &show, &offset) != 0) {
153		    beep();
154		}
155		break;
156	    }
157	} else {
158	    beep();
159	}
160    }
161
162    dlg_del_window(dialog);
163    dlg_mouse_free_regions();
164    free(prompt);
165    return result;
166}
167