1*4c8945a0SNathan Whitehorn /* 2*4c8945a0SNathan Whitehorn * $Id: inputbox.c,v 1.64 2010/01/19 01:03:39 tom Exp $ 3*4c8945a0SNathan Whitehorn * 4*4c8945a0SNathan Whitehorn * inputbox.c -- implements the input box 5*4c8945a0SNathan Whitehorn * 6*4c8945a0SNathan Whitehorn * Copyright 2000-2009,2010 Thomas E. Dickey 7*4c8945a0SNathan Whitehorn * 8*4c8945a0SNathan Whitehorn * This program is free software; you can redistribute it and/or modify 9*4c8945a0SNathan Whitehorn * it under the terms of the GNU Lesser General Public License, version 2.1 10*4c8945a0SNathan Whitehorn * as published by the Free Software Foundation. 11*4c8945a0SNathan Whitehorn * 12*4c8945a0SNathan Whitehorn * This program is distributed in the hope that it will be useful, but 13*4c8945a0SNathan Whitehorn * WITHOUT ANY WARRANTY; without even the implied warranty of 14*4c8945a0SNathan Whitehorn * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15*4c8945a0SNathan Whitehorn * Lesser General Public License for more details. 16*4c8945a0SNathan Whitehorn * 17*4c8945a0SNathan Whitehorn * You should have received a copy of the GNU Lesser General Public 18*4c8945a0SNathan Whitehorn * License along with this program; if not, write to 19*4c8945a0SNathan Whitehorn * Free Software Foundation, Inc. 20*4c8945a0SNathan Whitehorn * 51 Franklin St., Fifth Floor 21*4c8945a0SNathan Whitehorn * Boston, MA 02110, USA. 22*4c8945a0SNathan Whitehorn * 23*4c8945a0SNathan Whitehorn * An earlier version of this program lists as authors: 24*4c8945a0SNathan Whitehorn * Savio Lam (lam836@cs.cuhk.hk) 25*4c8945a0SNathan Whitehorn */ 26*4c8945a0SNathan Whitehorn 27*4c8945a0SNathan Whitehorn #include <dialog.h> 28*4c8945a0SNathan Whitehorn #include <dlg_keys.h> 29*4c8945a0SNathan Whitehorn 30*4c8945a0SNathan Whitehorn #define sTEXT -1 31*4c8945a0SNathan Whitehorn 32*4c8945a0SNathan Whitehorn #define NAVIGATE_BINDINGS \ 33*4c8945a0SNathan Whitehorn DLG_KEYS_DATA( DLGK_FIELD_NEXT, KEY_DOWN ), \ 34*4c8945a0SNathan Whitehorn DLG_KEYS_DATA( DLGK_FIELD_NEXT, KEY_RIGHT ), \ 35*4c8945a0SNathan Whitehorn DLG_KEYS_DATA( DLGK_FIELD_NEXT, TAB ), \ 36*4c8945a0SNathan Whitehorn DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_BTAB ), \ 37*4c8945a0SNathan Whitehorn DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_LEFT ), \ 38*4c8945a0SNathan Whitehorn DLG_KEYS_DATA( DLGK_FIELD_PREV, KEY_UP ) 39*4c8945a0SNathan Whitehorn 40*4c8945a0SNathan Whitehorn /* 41*4c8945a0SNathan Whitehorn * Display a dialog box for entering a string 42*4c8945a0SNathan Whitehorn */ 43*4c8945a0SNathan Whitehorn int 44*4c8945a0SNathan Whitehorn dialog_inputbox(const char *title, const char *cprompt, int height, int width, 45*4c8945a0SNathan Whitehorn const char *init, const int password) 46*4c8945a0SNathan Whitehorn { 47*4c8945a0SNathan Whitehorn /* *INDENT-OFF* */ 48*4c8945a0SNathan Whitehorn static DLG_KEYS_BINDING binding[] = { 49*4c8945a0SNathan Whitehorn ENTERKEY_BINDINGS, 50*4c8945a0SNathan Whitehorn NAVIGATE_BINDINGS, 51*4c8945a0SNathan Whitehorn END_KEYS_BINDING 52*4c8945a0SNathan Whitehorn }; 53*4c8945a0SNathan Whitehorn static DLG_KEYS_BINDING binding2[] = { 54*4c8945a0SNathan Whitehorn INPUTSTR_BINDINGS, 55*4c8945a0SNathan Whitehorn ENTERKEY_BINDINGS, 56*4c8945a0SNathan Whitehorn NAVIGATE_BINDINGS, 57*4c8945a0SNathan Whitehorn END_KEYS_BINDING 58*4c8945a0SNathan Whitehorn }; 59*4c8945a0SNathan Whitehorn /* *INDENT-ON* */ 60*4c8945a0SNathan Whitehorn 61*4c8945a0SNathan Whitehorn #ifdef KEY_RESIZE 62*4c8945a0SNathan Whitehorn int old_height = height; 63*4c8945a0SNathan Whitehorn int old_width = width; 64*4c8945a0SNathan Whitehorn #endif 65*4c8945a0SNathan Whitehorn int xorg, yorg; 66*4c8945a0SNathan Whitehorn int x, y, box_y, box_x, box_width; 67*4c8945a0SNathan Whitehorn int show_buttons; 68*4c8945a0SNathan Whitehorn int col_offset = 0; 69*4c8945a0SNathan Whitehorn int chr_offset = 0; 70*4c8945a0SNathan Whitehorn int key, fkey, code; 71*4c8945a0SNathan Whitehorn int result = DLG_EXIT_UNKNOWN; 72*4c8945a0SNathan Whitehorn int state; 73*4c8945a0SNathan Whitehorn int first; 74*4c8945a0SNathan Whitehorn char *input; 75*4c8945a0SNathan Whitehorn WINDOW *dialog; 76*4c8945a0SNathan Whitehorn WINDOW *editor; 77*4c8945a0SNathan Whitehorn char *prompt = dlg_strclone(cprompt); 78*4c8945a0SNathan Whitehorn const char **buttons = dlg_ok_labels(); 79*4c8945a0SNathan Whitehorn 80*4c8945a0SNathan Whitehorn dlg_does_output(); 81*4c8945a0SNathan Whitehorn 82*4c8945a0SNathan Whitehorn dlg_tab_correct_str(prompt); 83*4c8945a0SNathan Whitehorn 84*4c8945a0SNathan Whitehorn /* Set up the initial value */ 85*4c8945a0SNathan Whitehorn input = dlg_set_result(init); 86*4c8945a0SNathan Whitehorn 87*4c8945a0SNathan Whitehorn #ifdef KEY_RESIZE 88*4c8945a0SNathan Whitehorn retry: 89*4c8945a0SNathan Whitehorn #endif 90*4c8945a0SNathan Whitehorn show_buttons = TRUE; 91*4c8945a0SNathan Whitehorn state = dialog_vars.defaultno ? dlg_defaultno_button() : sTEXT; 92*4c8945a0SNathan Whitehorn first = (state == sTEXT); 93*4c8945a0SNathan Whitehorn key = fkey = 0; 94*4c8945a0SNathan Whitehorn 95*4c8945a0SNathan Whitehorn if (init != NULL) { 96*4c8945a0SNathan Whitehorn dlg_auto_size(title, prompt, &height, &width, 5, 97*4c8945a0SNathan Whitehorn MIN(MAX(dlg_count_columns(init) + 7, 26), 98*4c8945a0SNathan Whitehorn SCOLS - (dialog_vars.begin_set ? 99*4c8945a0SNathan Whitehorn dialog_vars.begin_x : 0))); 100*4c8945a0SNathan Whitehorn chr_offset = (int) strlen(init); 101*4c8945a0SNathan Whitehorn } else { 102*4c8945a0SNathan Whitehorn dlg_auto_size(title, prompt, &height, &width, 5, 26); 103*4c8945a0SNathan Whitehorn } 104*4c8945a0SNathan Whitehorn dlg_button_layout(buttons, &width); 105*4c8945a0SNathan Whitehorn dlg_print_size(height, width); 106*4c8945a0SNathan Whitehorn dlg_ctl_size(height, width); 107*4c8945a0SNathan Whitehorn 108*4c8945a0SNathan Whitehorn xorg = dlg_box_x_ordinate(width); 109*4c8945a0SNathan Whitehorn yorg = dlg_box_y_ordinate(height); 110*4c8945a0SNathan Whitehorn 111*4c8945a0SNathan Whitehorn dialog = dlg_new_window(height, width, yorg, xorg); 112*4c8945a0SNathan Whitehorn dlg_register_window(dialog, "inputbox", binding); 113*4c8945a0SNathan Whitehorn dlg_register_buttons(dialog, "inputbox", buttons); 114*4c8945a0SNathan Whitehorn 115*4c8945a0SNathan Whitehorn dlg_mouse_setbase(xorg, yorg); 116*4c8945a0SNathan Whitehorn 117*4c8945a0SNathan Whitehorn dlg_draw_box(dialog, 0, 0, height, width, dialog_attr, border_attr); 118*4c8945a0SNathan Whitehorn dlg_draw_bottom_box(dialog); 119*4c8945a0SNathan Whitehorn dlg_draw_title(dialog, title); 120*4c8945a0SNathan Whitehorn 121*4c8945a0SNathan Whitehorn wattrset(dialog, dialog_attr); 122*4c8945a0SNathan Whitehorn dlg_print_autowrap(dialog, prompt, height, width); 123*4c8945a0SNathan Whitehorn 124*4c8945a0SNathan Whitehorn /* Draw the input field box */ 125*4c8945a0SNathan Whitehorn box_width = width - 6; 126*4c8945a0SNathan Whitehorn getyx(dialog, y, x); 127*4c8945a0SNathan Whitehorn box_y = y + 2; 128*4c8945a0SNathan Whitehorn box_x = (width - box_width) / 2; 129*4c8945a0SNathan Whitehorn dlg_mouse_mkregion(y + 1, box_x - 1, 3, box_width + 2, 'i'); 130*4c8945a0SNathan Whitehorn dlg_draw_box(dialog, y + 1, box_x - 1, 3, box_width + 2, 131*4c8945a0SNathan Whitehorn border_attr, dialog_attr); 132*4c8945a0SNathan Whitehorn 133*4c8945a0SNathan Whitehorn /* Make a window for the input-field, to associate bindings */ 134*4c8945a0SNathan Whitehorn editor = dlg_sub_window(dialog, 1, box_width, yorg + box_y, xorg + box_x); 135*4c8945a0SNathan Whitehorn dlg_register_window(editor, "inputbox", binding2); 136*4c8945a0SNathan Whitehorn 137*4c8945a0SNathan Whitehorn while (result == DLG_EXIT_UNKNOWN) { 138*4c8945a0SNathan Whitehorn int edit = 0; 139*4c8945a0SNathan Whitehorn 140*4c8945a0SNathan Whitehorn /* 141*4c8945a0SNathan Whitehorn * The last field drawn determines where the cursor is shown: 142*4c8945a0SNathan Whitehorn */ 143*4c8945a0SNathan Whitehorn if (show_buttons) { 144*4c8945a0SNathan Whitehorn show_buttons = FALSE; 145*4c8945a0SNathan Whitehorn col_offset = dlg_edit_offset(input, chr_offset, box_width); 146*4c8945a0SNathan Whitehorn (void) wmove(dialog, box_y, box_x + col_offset); 147*4c8945a0SNathan Whitehorn dlg_draw_buttons(dialog, height - 2, 0, buttons, state, FALSE, width); 148*4c8945a0SNathan Whitehorn } 149*4c8945a0SNathan Whitehorn 150*4c8945a0SNathan Whitehorn if (!first) { 151*4c8945a0SNathan Whitehorn key = dlg_mouse_wgetch((state == sTEXT) ? editor : dialog, &fkey); 152*4c8945a0SNathan Whitehorn if (dlg_result_key(key, fkey, &result)) 153*4c8945a0SNathan Whitehorn break; 154*4c8945a0SNathan Whitehorn } 155*4c8945a0SNathan Whitehorn 156*4c8945a0SNathan Whitehorn /* 157*4c8945a0SNathan Whitehorn * Handle mouse clicks first, since we want to know if this is a button, 158*4c8945a0SNathan Whitehorn * or something that dlg_edit_string() should handle. 159*4c8945a0SNathan Whitehorn */ 160*4c8945a0SNathan Whitehorn if (fkey 161*4c8945a0SNathan Whitehorn && is_DLGK_MOUSE(key) 162*4c8945a0SNathan Whitehorn && (code = dlg_ok_buttoncode(key - M_EVENT)) >= 0) { 163*4c8945a0SNathan Whitehorn result = code; 164*4c8945a0SNathan Whitehorn continue; 165*4c8945a0SNathan Whitehorn } 166*4c8945a0SNathan Whitehorn 167*4c8945a0SNathan Whitehorn if (state == sTEXT) { /* Input box selected */ 168*4c8945a0SNathan Whitehorn edit = dlg_edit_string(input, &chr_offset, key, fkey, first); 169*4c8945a0SNathan Whitehorn 170*4c8945a0SNathan Whitehorn if (edit) { 171*4c8945a0SNathan Whitehorn dlg_show_string(dialog, input, chr_offset, inputbox_attr, 172*4c8945a0SNathan Whitehorn box_y, box_x, box_width, password, first); 173*4c8945a0SNathan Whitehorn first = FALSE; 174*4c8945a0SNathan Whitehorn continue; 175*4c8945a0SNathan Whitehorn } else if (first) { 176*4c8945a0SNathan Whitehorn first = FALSE; 177*4c8945a0SNathan Whitehorn continue; 178*4c8945a0SNathan Whitehorn } 179*4c8945a0SNathan Whitehorn } 180*4c8945a0SNathan Whitehorn 181*4c8945a0SNathan Whitehorn /* handle non-functionkeys */ 182*4c8945a0SNathan Whitehorn if (!fkey && (code = dlg_char_to_button(key, buttons)) >= 0) { 183*4c8945a0SNathan Whitehorn dlg_del_window(dialog); 184*4c8945a0SNathan Whitehorn result = dlg_ok_buttoncode(code); 185*4c8945a0SNathan Whitehorn continue; 186*4c8945a0SNathan Whitehorn } 187*4c8945a0SNathan Whitehorn 188*4c8945a0SNathan Whitehorn /* handle functionkeys */ 189*4c8945a0SNathan Whitehorn if (fkey) { 190*4c8945a0SNathan Whitehorn switch (key) { 191*4c8945a0SNathan Whitehorn case DLGK_MOUSE('i'): /* mouse enter events */ 192*4c8945a0SNathan Whitehorn state = 0; 193*4c8945a0SNathan Whitehorn /* FALLTHRU */ 194*4c8945a0SNathan Whitehorn case DLGK_FIELD_PREV: 195*4c8945a0SNathan Whitehorn show_buttons = TRUE; 196*4c8945a0SNathan Whitehorn state = dlg_prev_ok_buttonindex(state, sTEXT); 197*4c8945a0SNathan Whitehorn break; 198*4c8945a0SNathan Whitehorn case DLGK_FIELD_NEXT: 199*4c8945a0SNathan Whitehorn show_buttons = TRUE; 200*4c8945a0SNathan Whitehorn state = dlg_next_ok_buttonindex(state, sTEXT); 201*4c8945a0SNathan Whitehorn break; 202*4c8945a0SNathan Whitehorn case ' ': /* FIXME: conflict with inputstr.c */ 203*4c8945a0SNathan Whitehorn case DLGK_ENTER: 204*4c8945a0SNathan Whitehorn dlg_del_window(dialog); 205*4c8945a0SNathan Whitehorn result = (state >= 0) ? dlg_ok_buttoncode(state) : DLG_EXIT_OK; 206*4c8945a0SNathan Whitehorn break; 207*4c8945a0SNathan Whitehorn #ifdef KEY_RESIZE 208*4c8945a0SNathan Whitehorn case KEY_RESIZE: 209*4c8945a0SNathan Whitehorn /* reset data */ 210*4c8945a0SNathan Whitehorn height = old_height; 211*4c8945a0SNathan Whitehorn width = old_width; 212*4c8945a0SNathan Whitehorn /* repaint */ 213*4c8945a0SNathan Whitehorn dlg_clear(); 214*4c8945a0SNathan Whitehorn dlg_del_window(dialog); 215*4c8945a0SNathan Whitehorn refresh(); 216*4c8945a0SNathan Whitehorn dlg_mouse_free_regions(); 217*4c8945a0SNathan Whitehorn goto retry; 218*4c8945a0SNathan Whitehorn #endif 219*4c8945a0SNathan Whitehorn default: 220*4c8945a0SNathan Whitehorn beep(); 221*4c8945a0SNathan Whitehorn break; 222*4c8945a0SNathan Whitehorn } 223*4c8945a0SNathan Whitehorn } else { 224*4c8945a0SNathan Whitehorn beep(); 225*4c8945a0SNathan Whitehorn } 226*4c8945a0SNathan Whitehorn } 227*4c8945a0SNathan Whitehorn 228*4c8945a0SNathan Whitehorn dlg_unregister_window(editor); 229*4c8945a0SNathan Whitehorn dlg_del_window(dialog); 230*4c8945a0SNathan Whitehorn dlg_mouse_free_regions(); 231*4c8945a0SNathan Whitehorn free(prompt); 232*4c8945a0SNathan Whitehorn return result; 233*4c8945a0SNathan Whitehorn } 234