OSDN Git Service

Replace FSF snail mail address with URLs
[uclinux-h8/uClibc.git] / extra / config / lxdialog / inputbox.c
1 /*
2  *  inputbox.c -- implements the input box
3  *
4  *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
5  *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
6  *
7  *  This program is free software; you can redistribute it and/or
8  *  modify it under the terms of the GNU General Public License
9  *  as published by the Free Software Foundation; either version 2
10  *  of the License, or (at your option) any later version.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include "dialog.h"
22
23 char dialog_input_result[MAX_LEN + 1];
24
25 /*
26  *  Print the termination buttons
27  */
28 static void print_buttons(WINDOW * dialog, int height, int width, int selected)
29 {
30         int x = width / 2 - 11;
31         int y = height - 2;
32
33         print_button(dialog, gettext("  Ok  "), y, x, selected == 0);
34         print_button(dialog, gettext(" Help "), y, x + 14, selected == 1);
35
36         wmove(dialog, y, x + 1 + 14 * selected);
37         wrefresh(dialog);
38 }
39
40 /*
41  * Display a dialog box for inputing a string
42  */
43 int dialog_inputbox(const char *title, const char *prompt, int height, int width,
44                     const char *init)
45 {
46         int i, x, y, box_y, box_x, box_width;
47         int input_x = 0, scroll = 0, key = 0, button = -1;
48         char *instr = dialog_input_result;
49         WINDOW *dialog;
50
51         if (!init)
52                 instr[0] = '\0';
53         else
54                 strcpy(instr, init);
55
56 do_resize:
57         if (getmaxy(stdscr) <= (height - 2))
58                 return -ERRDISPLAYTOOSMALL;
59         if (getmaxx(stdscr) <= (width - 2))
60                 return -ERRDISPLAYTOOSMALL;
61
62         /* center dialog box on screen */
63         x = (COLS - width) / 2;
64         y = (LINES - height) / 2;
65
66         draw_shadow(stdscr, y, x, height, width);
67
68         dialog = newwin(height, width, y, x);
69         keypad(dialog, TRUE);
70
71         draw_box(dialog, 0, 0, height, width,
72                  dlg.dialog.atr, dlg.border.atr);
73         wattrset(dialog, dlg.border.atr);
74         mvwaddch(dialog, height - 3, 0, ACS_LTEE);
75         for (i = 0; i < width - 2; i++)
76                 waddch(dialog, ACS_HLINE);
77         wattrset(dialog, dlg.dialog.atr);
78         waddch(dialog, ACS_RTEE);
79
80         print_title(dialog, title, width);
81
82         wattrset(dialog, dlg.dialog.atr);
83         print_autowrap(dialog, prompt, width - 2, 1, 3);
84
85         /* Draw the input field box */
86         box_width = width - 6;
87         getyx(dialog, y, x);
88         box_y = y + 2;
89         box_x = (width - box_width) / 2;
90         draw_box(dialog, y + 1, box_x - 1, 3, box_width + 2,
91                  dlg.dialog.atr, dlg.border.atr);
92
93         print_buttons(dialog, height, width, 0);
94
95         /* Set up the initial value */
96         wmove(dialog, box_y, box_x);
97         wattrset(dialog, dlg.inputbox.atr);
98
99         input_x = strlen(instr);
100
101         if (input_x >= box_width) {
102                 scroll = input_x - box_width + 1;
103                 input_x = box_width - 1;
104                 for (i = 0; i < box_width - 1; i++)
105                         waddch(dialog, instr[scroll + i]);
106         } else {
107                 waddstr(dialog, instr);
108         }
109
110         wmove(dialog, box_y, box_x + input_x);
111
112         wrefresh(dialog);
113
114         while (key != KEY_ESC) {
115                 key = wgetch(dialog);
116
117                 if (button == -1) {     /* Input box selected */
118                         switch (key) {
119                         case TAB:
120                         case KEY_UP:
121                         case KEY_DOWN:
122                                 break;
123                         case KEY_LEFT:
124                                 continue;
125                         case KEY_RIGHT:
126                                 continue;
127                         case KEY_BACKSPACE:
128                         case 127:
129                                 if (input_x || scroll) {
130                                         wattrset(dialog, dlg.inputbox.atr);
131                                         if (!input_x) {
132                                                 scroll = scroll < box_width - 1 ? 0 : scroll - (box_width - 1);
133                                                 wmove(dialog, box_y, box_x);
134                                                 for (i = 0; i < box_width; i++)
135                                                         waddch(dialog,
136                                                                instr[scroll + input_x + i] ?
137                                                                instr[scroll + input_x + i] : ' ');
138                                                 input_x = strlen(instr) - scroll;
139                                         } else
140                                                 input_x--;
141                                         instr[scroll + input_x] = '\0';
142                                         mvwaddch(dialog, box_y, input_x + box_x, ' ');
143                                         wmove(dialog, box_y, input_x + box_x);
144                                         wrefresh(dialog);
145                                 }
146                                 continue;
147                         default:
148                                 if (key < 0x100 && isprint(key)) {
149                                         if (scroll + input_x < MAX_LEN) {
150                                                 wattrset(dialog, dlg.inputbox.atr);
151                                                 instr[scroll + input_x] = key;
152                                                 instr[scroll + input_x + 1] = '\0';
153                                                 if (input_x == box_width - 1) {
154                                                         scroll++;
155                                                         wmove(dialog, box_y, box_x);
156                                                         for (i = 0; i < box_width - 1; i++)
157                                                                 waddch(dialog, instr [scroll + i]);
158                                                 } else {
159                                                         wmove(dialog, box_y, input_x++ + box_x);
160                                                         waddch(dialog, key);
161                                                 }
162                                                 wrefresh(dialog);
163                                         } else
164                                                 flash();        /* Alarm user about overflow */
165                                         continue;
166                                 }
167                         }
168                 }
169                 switch (key) {
170                 case 'O':
171                 case 'o':
172                         delwin(dialog);
173                         return 0;
174                 case 'H':
175                 case 'h':
176                         delwin(dialog);
177                         return 1;
178                 case KEY_UP:
179                 case KEY_LEFT:
180                         switch (button) {
181                         case -1:
182                                 button = 1;     /* Indicates "Cancel" button is selected */
183                                 print_buttons(dialog, height, width, 1);
184                                 break;
185                         case 0:
186                                 button = -1;    /* Indicates input box is selected */
187                                 print_buttons(dialog, height, width, 0);
188                                 wmove(dialog, box_y, box_x + input_x);
189                                 wrefresh(dialog);
190                                 break;
191                         case 1:
192                                 button = 0;     /* Indicates "OK" button is selected */
193                                 print_buttons(dialog, height, width, 0);
194                                 break;
195                         }
196                         break;
197                 case TAB:
198                 case KEY_DOWN:
199                 case KEY_RIGHT:
200                         switch (button) {
201                         case -1:
202                                 button = 0;     /* Indicates "OK" button is selected */
203                                 print_buttons(dialog, height, width, 0);
204                                 break;
205                         case 0:
206                                 button = 1;     /* Indicates "Cancel" button is selected */
207                                 print_buttons(dialog, height, width, 1);
208                                 break;
209                         case 1:
210                                 button = -1;    /* Indicates input box is selected */
211                                 print_buttons(dialog, height, width, 0);
212                                 wmove(dialog, box_y, box_x + input_x);
213                                 wrefresh(dialog);
214                                 break;
215                         }
216                         break;
217                 case ' ':
218                 case '\n':
219                         delwin(dialog);
220                         return (button == -1 ? 0 : button);
221                 case 'X':
222                 case 'x':
223                         key = KEY_ESC;
224                         break;
225                 case KEY_ESC:
226                         key = on_key_esc(dialog);
227                         break;
228                 case KEY_RESIZE:
229                         delwin(dialog);
230                         on_key_resize();
231                         goto do_resize;
232                 }
233         }
234
235         delwin(dialog);
236         return KEY_ESC;         /* ESC pressed */
237 }