1c76f0793SBaptiste Daroussin /*- 2c76f0793SBaptiste Daroussin * SPDX-License-Identifier: BSD-2-Clause 3c76f0793SBaptiste Daroussin * 4*263660c0SAlfonso Siciliano * Copyright (c) 2021-2022 Alfonso Sabato Siciliano 5c76f0793SBaptiste Daroussin * 6c76f0793SBaptiste Daroussin * Redistribution and use in source and binary forms, with or without 7c76f0793SBaptiste Daroussin * modification, are permitted provided that the following conditions 8c76f0793SBaptiste Daroussin * are met: 9c76f0793SBaptiste Daroussin * 1. Redistributions of source code must retain the above copyright 10c76f0793SBaptiste Daroussin * notice, this list of conditions and the following disclaimer. 11c76f0793SBaptiste Daroussin * 2. Redistributions in binary form must reproduce the above copyright 12c76f0793SBaptiste Daroussin * notice, this list of conditions and the following disclaimer in the 13c76f0793SBaptiste Daroussin * documentation and/or other materials provided with the distribution. 14c76f0793SBaptiste Daroussin * 15c76f0793SBaptiste Daroussin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16c76f0793SBaptiste Daroussin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17c76f0793SBaptiste Daroussin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18c76f0793SBaptiste Daroussin * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19c76f0793SBaptiste Daroussin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20c76f0793SBaptiste Daroussin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21c76f0793SBaptiste Daroussin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22c76f0793SBaptiste Daroussin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23c76f0793SBaptiste Daroussin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24c76f0793SBaptiste Daroussin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25c76f0793SBaptiste Daroussin * SUCH DAMAGE. 26c76f0793SBaptiste Daroussin */ 27c76f0793SBaptiste Daroussin 28f499134dSBaptiste Daroussin #include <sys/param.h> 29f499134dSBaptiste Daroussin 30f499134dSBaptiste Daroussin #include <ctype.h> 31c76f0793SBaptiste Daroussin #include <form.h> 32d93b4d32SBaptiste Daroussin #include <stdlib.h> 33d93b4d32SBaptiste Daroussin #include <string.h> 34c76f0793SBaptiste Daroussin 35c76f0793SBaptiste Daroussin #include "bsddialog.h" 36c76f0793SBaptiste Daroussin #include "bsddialog_theme.h" 37*263660c0SAlfonso Siciliano #include "lib_util.h" 38c76f0793SBaptiste Daroussin 39*263660c0SAlfonso Siciliano #define REDRAWFORM 19860214 /* magic number */ 40f499134dSBaptiste Daroussin #define ISFIELDHIDDEN(item) (item.flags & BSDDIALOG_FIELDHIDDEN) 41f499134dSBaptiste Daroussin #define ISFIELDREADONLY(item) (item.flags & BSDDIALOG_FIELDREADONLY) 42f499134dSBaptiste Daroussin 43c76f0793SBaptiste Daroussin extern struct bsddialog_theme t; 44c76f0793SBaptiste Daroussin 45*263660c0SAlfonso Siciliano /* field_userptr for private buffer and view options */ 46f499134dSBaptiste Daroussin struct myfield { 47d93b4d32SBaptiste Daroussin int buflen; 48f499134dSBaptiste Daroussin char *buf; 49f499134dSBaptiste Daroussin int pos; 50d93b4d32SBaptiste Daroussin int maxpos; 51f499134dSBaptiste Daroussin bool secure; 52f499134dSBaptiste Daroussin int securech; 53*263660c0SAlfonso Siciliano const char *bottomdesc; 54f499134dSBaptiste Daroussin }; 55f499134dSBaptiste Daroussin #define GETMYFIELD(field) ((struct myfield*)field_userptr(field)) 56f499134dSBaptiste Daroussin #define GETMYFIELD2(form) ((struct myfield*)field_userptr(current_field(form))) 57f499134dSBaptiste Daroussin 58f499134dSBaptiste Daroussin static void insertch(struct myfield *mf, int ch) 59c76f0793SBaptiste Daroussin { 60f499134dSBaptiste Daroussin int i; 61f499134dSBaptiste Daroussin 62d93b4d32SBaptiste Daroussin if (mf->buflen > mf->maxpos) 63f499134dSBaptiste Daroussin return; 64f499134dSBaptiste Daroussin 65d93b4d32SBaptiste Daroussin for (i = mf->buflen; i >= mf->pos; i--) { 66f499134dSBaptiste Daroussin mf->buf[i+1] = mf->buf[i]; 67c76f0793SBaptiste Daroussin } 68c76f0793SBaptiste Daroussin 69f499134dSBaptiste Daroussin mf->buf[mf->pos] = ch; 70f499134dSBaptiste Daroussin mf->pos += 1; 71d93b4d32SBaptiste Daroussin if (mf->pos > mf->maxpos) 72d93b4d32SBaptiste Daroussin mf->pos = mf->maxpos; 73d93b4d32SBaptiste Daroussin mf->buflen += 1; 74d93b4d32SBaptiste Daroussin mf->buf[mf->buflen] = '\0'; 75f499134dSBaptiste Daroussin } 76f499134dSBaptiste Daroussin 77f499134dSBaptiste Daroussin static void shiftleft(struct myfield *mf) 78f499134dSBaptiste Daroussin { 79f499134dSBaptiste Daroussin int i, last; 80f499134dSBaptiste Daroussin 81d93b4d32SBaptiste Daroussin for (i = mf->pos; i < mf->buflen -1; i++) { 82f499134dSBaptiste Daroussin mf->buf[i] = mf->buf[i+1]; 83f499134dSBaptiste Daroussin } 84f499134dSBaptiste Daroussin 85d93b4d32SBaptiste Daroussin last = mf->buflen > 0 ? mf->buflen -1 : 0; 86f499134dSBaptiste Daroussin mf->buf[last] = '\0'; 87d93b4d32SBaptiste Daroussin mf->buflen = last; 88f499134dSBaptiste Daroussin } 89c76f0793SBaptiste Daroussin 908c4f4028SBaptiste Daroussin static void print_bottomdesc(struct myfield *mf) 918c4f4028SBaptiste Daroussin { 92*263660c0SAlfonso Siciliano move(SCREENLINES - 1, 2); 938c4f4028SBaptiste Daroussin clrtoeol(); 948c4f4028SBaptiste Daroussin if (mf->bottomdesc != NULL) { 958c4f4028SBaptiste Daroussin addstr(mf->bottomdesc); 968c4f4028SBaptiste Daroussin refresh(); 978c4f4028SBaptiste Daroussin } 988c4f4028SBaptiste Daroussin } 998c4f4028SBaptiste Daroussin 100d93b4d32SBaptiste Daroussin int 101*263660c0SAlfonso Siciliano return_values(struct bsddialog_conf *conf, int output, int nitems, 102d93b4d32SBaptiste Daroussin struct bsddialog_formitem *items, FORM *form, FIELD **cfield) 103d93b4d32SBaptiste Daroussin { 104*263660c0SAlfonso Siciliano int i; 105d93b4d32SBaptiste Daroussin struct myfield *mf; 106d93b4d32SBaptiste Daroussin 107*263660c0SAlfonso Siciliano if (output != BSDDIALOG_OK && conf->form.value_without_ok == false) 108*263660c0SAlfonso Siciliano return (output); 109d93b4d32SBaptiste Daroussin 110d93b4d32SBaptiste Daroussin form_driver(form, REQ_NEXT_FIELD); 111d93b4d32SBaptiste Daroussin form_driver(form, REQ_PREV_FIELD); 112d93b4d32SBaptiste Daroussin for (i = 0; i < nitems; i++) { 113d93b4d32SBaptiste Daroussin mf = GETMYFIELD(cfield[i]); 114d93b4d32SBaptiste Daroussin items[i].value = strdup(mf->buf); 115d93b4d32SBaptiste Daroussin if (items[i].value == NULL) 116d93b4d32SBaptiste Daroussin RETURN_ERROR("Cannot allocate memory for form value"); 117d93b4d32SBaptiste Daroussin } 118d93b4d32SBaptiste Daroussin 119d93b4d32SBaptiste Daroussin return (output); 120d93b4d32SBaptiste Daroussin } 121d93b4d32SBaptiste Daroussin 122c76f0793SBaptiste Daroussin static int 123*263660c0SAlfonso Siciliano form_handler(struct bsddialog_conf *conf, WINDOW *widget, struct buttons bs, 124*263660c0SAlfonso Siciliano WINDOW *formwin, FORM *form, FIELD **cfield, int nitems, 125f499134dSBaptiste Daroussin struct bsddialog_formitem *items) 126c76f0793SBaptiste Daroussin { 127*263660c0SAlfonso Siciliano bool loop, buttupdate, informwin; 128f499134dSBaptiste Daroussin int i, input, output; 129f499134dSBaptiste Daroussin struct myfield *mf; 130c76f0793SBaptiste Daroussin 131f499134dSBaptiste Daroussin mf = GETMYFIELD2(form); 1328c4f4028SBaptiste Daroussin print_bottomdesc(mf); 133d93b4d32SBaptiste Daroussin pos_form_cursor(form); 134d93b4d32SBaptiste Daroussin form_driver(form, REQ_END_LINE); 135d93b4d32SBaptiste Daroussin mf->pos = MIN(mf->buflen, mf->maxpos); 136d93b4d32SBaptiste Daroussin curs_set(2); 137*263660c0SAlfonso Siciliano informwin = true; 138*263660c0SAlfonso Siciliano 139d93b4d32SBaptiste Daroussin bs.curr = -1; 140*263660c0SAlfonso Siciliano buttupdate = true; 141*263660c0SAlfonso Siciliano 142*263660c0SAlfonso Siciliano loop = true; 143c76f0793SBaptiste Daroussin while (loop) { 144c76f0793SBaptiste Daroussin if (buttupdate) { 145*263660c0SAlfonso Siciliano draw_buttons(widget, bs, !informwin); 146c76f0793SBaptiste Daroussin wrefresh(widget); 147c76f0793SBaptiste Daroussin buttupdate = false; 148c76f0793SBaptiste Daroussin } 149f499134dSBaptiste Daroussin wrefresh(formwin); 150c76f0793SBaptiste Daroussin input = getch(); 151c76f0793SBaptiste Daroussin switch(input) { 152f499134dSBaptiste Daroussin case KEY_ENTER: 153f499134dSBaptiste Daroussin case 10: /* Enter */ 154f499134dSBaptiste Daroussin if (informwin) 155c76f0793SBaptiste Daroussin break; 156*263660c0SAlfonso Siciliano output = return_values(conf, bs.value[bs.curr], nitems, 157*263660c0SAlfonso Siciliano items, form, cfield); 1588c4f4028SBaptiste Daroussin loop = false; 159c76f0793SBaptiste Daroussin break; 160c76f0793SBaptiste Daroussin case 27: /* Esc */ 161*263660c0SAlfonso Siciliano if (conf->key.enable_esc) { 162*263660c0SAlfonso Siciliano output = return_values(conf, BSDDIALOG_ESC, 163*263660c0SAlfonso Siciliano nitems, items, form, cfield); 164c76f0793SBaptiste Daroussin loop = false; 165*263660c0SAlfonso Siciliano } 166c76f0793SBaptiste Daroussin break; 167f499134dSBaptiste Daroussin case '\t': /* TAB */ 168f499134dSBaptiste Daroussin if (informwin) { 169c76f0793SBaptiste Daroussin bs.curr = 0; 170f499134dSBaptiste Daroussin informwin = false; 171c76f0793SBaptiste Daroussin curs_set(0); 172c76f0793SBaptiste Daroussin } else { 173c76f0793SBaptiste Daroussin bs.curr++; 174f499134dSBaptiste Daroussin informwin = bs.curr >= (int)bs.nbuttons ? 175f499134dSBaptiste Daroussin true : false; 176f499134dSBaptiste Daroussin if (informwin) { 177c76f0793SBaptiste Daroussin curs_set(2); 178c76f0793SBaptiste Daroussin pos_form_cursor(form); 179c76f0793SBaptiste Daroussin } 180c76f0793SBaptiste Daroussin } 181c76f0793SBaptiste Daroussin buttupdate = true; 182c76f0793SBaptiste Daroussin break; 183c76f0793SBaptiste Daroussin case KEY_LEFT: 184f499134dSBaptiste Daroussin if (informwin) { 185c76f0793SBaptiste Daroussin form_driver(form, REQ_PREV_CHAR); 186f499134dSBaptiste Daroussin mf = GETMYFIELD2(form); 187f499134dSBaptiste Daroussin if (mf->pos > 0) 188f499134dSBaptiste Daroussin mf->pos -= 1; 189c76f0793SBaptiste Daroussin } else { 190c76f0793SBaptiste Daroussin if (bs.curr > 0) { 191c76f0793SBaptiste Daroussin bs.curr--; 192c76f0793SBaptiste Daroussin buttupdate = true; 193c76f0793SBaptiste Daroussin } 194c76f0793SBaptiste Daroussin } 195c76f0793SBaptiste Daroussin break; 196c76f0793SBaptiste Daroussin case KEY_RIGHT: 197f499134dSBaptiste Daroussin if (informwin) { 198f499134dSBaptiste Daroussin mf = GETMYFIELD2(form); 199d93b4d32SBaptiste Daroussin if (mf->pos >= mf->buflen) 200f499134dSBaptiste Daroussin break; 201f499134dSBaptiste Daroussin mf->pos += 1; 202c76f0793SBaptiste Daroussin form_driver(form, REQ_NEXT_CHAR); 203c76f0793SBaptiste Daroussin } else { 204c76f0793SBaptiste Daroussin if (bs.curr < (int) bs.nbuttons - 1) { 205c76f0793SBaptiste Daroussin bs.curr++; 206c76f0793SBaptiste Daroussin buttupdate = true; 207c76f0793SBaptiste Daroussin } 208c76f0793SBaptiste Daroussin } 209c76f0793SBaptiste Daroussin break; 210c76f0793SBaptiste Daroussin case KEY_UP: 211c76f0793SBaptiste Daroussin if (nitems < 2) 212c76f0793SBaptiste Daroussin break; 213f499134dSBaptiste Daroussin set_field_fore(current_field(form), t.form.fieldcolor); 214f499134dSBaptiste Daroussin set_field_back(current_field(form), t.form.fieldcolor); 215c76f0793SBaptiste Daroussin form_driver(form, REQ_PREV_FIELD); 216c76f0793SBaptiste Daroussin form_driver(form, REQ_END_LINE); 217f499134dSBaptiste Daroussin mf = GETMYFIELD2(form); 2188c4f4028SBaptiste Daroussin print_bottomdesc(mf); 219d93b4d32SBaptiste Daroussin mf->pos = MIN(mf->buflen, mf->maxpos); 220f499134dSBaptiste Daroussin set_field_fore(current_field(form), t.form.f_fieldcolor); 221f499134dSBaptiste Daroussin set_field_back(current_field(form), t.form.f_fieldcolor); 222c76f0793SBaptiste Daroussin break; 223c76f0793SBaptiste Daroussin case KEY_DOWN: 224c76f0793SBaptiste Daroussin if (nitems < 2) 225c76f0793SBaptiste Daroussin break; 226f499134dSBaptiste Daroussin set_field_fore(current_field(form), t.form.fieldcolor); 227f499134dSBaptiste Daroussin set_field_back(current_field(form), t.form.fieldcolor); 228c76f0793SBaptiste Daroussin form_driver(form, REQ_NEXT_FIELD); 229c76f0793SBaptiste Daroussin form_driver(form, REQ_END_LINE); 230f499134dSBaptiste Daroussin mf = GETMYFIELD2(form); 2318c4f4028SBaptiste Daroussin print_bottomdesc(mf); 232d93b4d32SBaptiste Daroussin mf->pos = MIN(mf->buflen, mf->maxpos); 233f499134dSBaptiste Daroussin set_field_fore(current_field(form), t.form.f_fieldcolor); 234f499134dSBaptiste Daroussin set_field_back(current_field(form), t.form.f_fieldcolor); 235c76f0793SBaptiste Daroussin break; 236c76f0793SBaptiste Daroussin case KEY_BACKSPACE: 237f499134dSBaptiste Daroussin case 127: /* Backspace */ 238f499134dSBaptiste Daroussin mf = GETMYFIELD2(form); 239f499134dSBaptiste Daroussin if (mf->pos <= 0) 240f499134dSBaptiste Daroussin break; 241c76f0793SBaptiste Daroussin form_driver(form, REQ_DEL_PREV); 242d93b4d32SBaptiste Daroussin form_driver(form, REQ_BEG_LINE); 243d93b4d32SBaptiste Daroussin mf->pos = mf->pos - 1; 244d93b4d32SBaptiste Daroussin for (i = 0; i < mf->pos; i++) 245d93b4d32SBaptiste Daroussin form_driver(form, REQ_NEXT_CHAR); 246f499134dSBaptiste Daroussin shiftleft(mf); 247c76f0793SBaptiste Daroussin break; 248c76f0793SBaptiste Daroussin case KEY_DC: 249c76f0793SBaptiste Daroussin form_driver(form, REQ_DEL_CHAR); 250f499134dSBaptiste Daroussin mf = GETMYFIELD2(form); 251d93b4d32SBaptiste Daroussin if (mf->pos < mf->buflen) 252f499134dSBaptiste Daroussin shiftleft(mf); 253f499134dSBaptiste Daroussin break; 254f499134dSBaptiste Daroussin case KEY_F(1): 2558c4f4028SBaptiste Daroussin if (conf->f1_file == NULL && conf->f1_message == NULL) 256f499134dSBaptiste Daroussin break; 257f499134dSBaptiste Daroussin if (f1help(conf) != 0) 258*263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 259f499134dSBaptiste Daroussin /* No Break */ 260f499134dSBaptiste Daroussin case KEY_RESIZE: 261f499134dSBaptiste Daroussin output = REDRAWFORM; 262f499134dSBaptiste Daroussin loop = false; 263c76f0793SBaptiste Daroussin break; 264c76f0793SBaptiste Daroussin default: 265f499134dSBaptiste Daroussin if (informwin) { 266f499134dSBaptiste Daroussin mf = GETMYFIELD2(form); 267f499134dSBaptiste Daroussin if (mf->secure) 268f499134dSBaptiste Daroussin form_driver(form, mf->securech); 269f499134dSBaptiste Daroussin else 270c76f0793SBaptiste Daroussin form_driver(form, input); 271f499134dSBaptiste Daroussin insertch(mf, input); 272f499134dSBaptiste Daroussin } 273f499134dSBaptiste Daroussin else { 274*263660c0SAlfonso Siciliano if (shortcut_buttons(input, &bs)) { 275*263660c0SAlfonso Siciliano output = return_values(conf, 276*263660c0SAlfonso Siciliano bs.value[bs.curr], nitems, items, 277*263660c0SAlfonso Siciliano form, cfield); 278f499134dSBaptiste Daroussin loop = false; 279f499134dSBaptiste Daroussin } 280f499134dSBaptiste Daroussin } 281c76f0793SBaptiste Daroussin break; 282c76f0793SBaptiste Daroussin } 283c76f0793SBaptiste Daroussin } 284c76f0793SBaptiste Daroussin 285c76f0793SBaptiste Daroussin curs_set(0); 286c76f0793SBaptiste Daroussin 287*263660c0SAlfonso Siciliano return (output); 288f499134dSBaptiste Daroussin } 289f499134dSBaptiste Daroussin 290f499134dSBaptiste Daroussin static int 291*263660c0SAlfonso Siciliano form_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h, int *w, 292*263660c0SAlfonso Siciliano const char *text, int linelen, unsigned int *formheight, int nitems, 293f499134dSBaptiste Daroussin struct buttons bs) 294f499134dSBaptiste Daroussin { 295*263660c0SAlfonso Siciliano int htext, wtext, menusize; 296*263660c0SAlfonso Siciliano 297*263660c0SAlfonso Siciliano if (cols == BSDDIALOG_AUTOSIZE || rows == BSDDIALOG_AUTOSIZE) { 298*263660c0SAlfonso Siciliano if (text_size(conf, rows, cols, text, &bs, *formheight + 2, 299*263660c0SAlfonso Siciliano linelen + 2, &htext, &wtext) != 0) 300*263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 301*263660c0SAlfonso Siciliano } 302*263660c0SAlfonso Siciliano 303*263660c0SAlfonso Siciliano if (cols == BSDDIALOG_AUTOSIZE) 304*263660c0SAlfonso Siciliano *w = widget_min_width(conf, wtext, linelen + 2, &bs); 305*263660c0SAlfonso Siciliano 306*263660c0SAlfonso Siciliano if (rows == BSDDIALOG_AUTOSIZE) { 307*263660c0SAlfonso Siciliano if (*formheight == 0) { 308*263660c0SAlfonso Siciliano menusize = widget_max_height(conf) - HBORDERS - 309*263660c0SAlfonso Siciliano 2 /*buttons*/ - htext; 310*263660c0SAlfonso Siciliano menusize = MIN(menusize, nitems + 2); 311*263660c0SAlfonso Siciliano *formheight = menusize - 2 < 0 ? 0 : menusize - 2; 312*263660c0SAlfonso Siciliano } 313*263660c0SAlfonso Siciliano else /* h autosize with fixed formheight */ 314*263660c0SAlfonso Siciliano menusize = *formheight + 2; 315*263660c0SAlfonso Siciliano 316*263660c0SAlfonso Siciliano *h = widget_min_height(conf, htext, menusize, true); 317*263660c0SAlfonso Siciliano } else { 318*263660c0SAlfonso Siciliano if (*formheight == 0) 319*263660c0SAlfonso Siciliano *formheight = MIN(rows-6-htext, nitems); 320*263660c0SAlfonso Siciliano } 321*263660c0SAlfonso Siciliano 322*263660c0SAlfonso Siciliano return (0); 323*263660c0SAlfonso Siciliano } 324*263660c0SAlfonso Siciliano 325*263660c0SAlfonso Siciliano static int 326*263660c0SAlfonso Siciliano form_checksize(int rows, int cols, const char *text, int formheight, int nitems, 327*263660c0SAlfonso Siciliano unsigned int linelen, struct buttons bs) 328*263660c0SAlfonso Siciliano { 329f499134dSBaptiste Daroussin int mincols, textrow, formrows; 330f499134dSBaptiste Daroussin 331f499134dSBaptiste Daroussin mincols = VBORDERS; 332f499134dSBaptiste Daroussin /* buttons */ 333f499134dSBaptiste Daroussin mincols += bs.nbuttons * bs.sizebutton; 334f499134dSBaptiste Daroussin mincols += bs.nbuttons > 0 ? (bs.nbuttons-1) * t.button.space : 0; 335*263660c0SAlfonso Siciliano mincols = MAX(mincols, (int)linelen + 4); 336f499134dSBaptiste Daroussin 337f499134dSBaptiste Daroussin if (cols < mincols) 338*263660c0SAlfonso Siciliano RETURN_ERROR("Few cols, width < size buttons or " 339*263660c0SAlfonso Siciliano "forms (label + field)"); 340f499134dSBaptiste Daroussin 341f499134dSBaptiste Daroussin textrow = text != NULL && strlen(text) > 0 ? 1 : 0; 342f499134dSBaptiste Daroussin 343f499134dSBaptiste Daroussin if (nitems > 0 && formheight == 0) 344*263660c0SAlfonso Siciliano RETURN_ERROR("fields > 0 but formheight == 0, probably " 345f499134dSBaptiste Daroussin "terminal too small"); 346f499134dSBaptiste Daroussin 347f499134dSBaptiste Daroussin formrows = nitems > 0 ? 3 : 0; 348f499134dSBaptiste Daroussin if (rows < 2 + 2 + formrows + textrow) 349f499134dSBaptiste Daroussin RETURN_ERROR("Few lines for this menus"); 350f499134dSBaptiste Daroussin 351*263660c0SAlfonso Siciliano return (0); 352f499134dSBaptiste Daroussin } 353f499134dSBaptiste Daroussin 354f499134dSBaptiste Daroussin int 355*263660c0SAlfonso Siciliano bsddialog_form(struct bsddialog_conf *conf, const char *text, int rows, 356*263660c0SAlfonso Siciliano int cols, unsigned int formheight, unsigned int nitems, 357f499134dSBaptiste Daroussin struct bsddialog_formitem *items) 358f499134dSBaptiste Daroussin { 359f499134dSBaptiste Daroussin WINDOW *widget, *formwin, *textpad, *shadow; 360*263660c0SAlfonso Siciliano int i, output, color, y, x, h, w; 361f499134dSBaptiste Daroussin FIELD **cfield; 362c76f0793SBaptiste Daroussin FORM *form; 363c76f0793SBaptiste Daroussin struct buttons bs; 364f499134dSBaptiste Daroussin struct myfield *myfields; 365f499134dSBaptiste Daroussin unsigned long maxline; 366c76f0793SBaptiste Daroussin 367*263660c0SAlfonso Siciliano /* disable form scrolling */ 368f499134dSBaptiste Daroussin if (formheight < nitems) 369f499134dSBaptiste Daroussin formheight = nitems; 370c76f0793SBaptiste Daroussin 371d93b4d32SBaptiste Daroussin for (i = 0; i < (int)nitems; i++) { 372d93b4d32SBaptiste Daroussin if (items[i].maxvaluelen == 0) 373d93b4d32SBaptiste Daroussin RETURN_ERROR("maxvaluelen cannot be zero"); 374d93b4d32SBaptiste Daroussin if (items[i].fieldlen == 0) 375d93b4d32SBaptiste Daroussin RETURN_ERROR("fieldlen cannot be zero"); 376d93b4d32SBaptiste Daroussin if (items[i].fieldlen > items[i].maxvaluelen) 377d93b4d32SBaptiste Daroussin RETURN_ERROR("fieldlen cannot be > maxvaluelen"); 378d93b4d32SBaptiste Daroussin } 379d93b4d32SBaptiste Daroussin 380f499134dSBaptiste Daroussin maxline = 0; 381f499134dSBaptiste Daroussin myfields = malloc(nitems * sizeof(struct myfield)); 382f499134dSBaptiste Daroussin cfield = calloc(nitems + 1, sizeof(FIELD*)); 383f499134dSBaptiste Daroussin for (i = 0; i < (int)nitems; i++) { 384f499134dSBaptiste Daroussin cfield[i] = new_field(1, items[i].fieldlen, items[i].yfield-1, 385f499134dSBaptiste Daroussin items[i].xfield-1, 0, 0); 386f499134dSBaptiste Daroussin field_opts_off(cfield[i], O_STATIC); 387f499134dSBaptiste Daroussin set_max_field(cfield[i], items[i].maxvaluelen); 388f499134dSBaptiste Daroussin set_field_buffer(cfield[i], 0, items[i].init); 389f499134dSBaptiste Daroussin 390d93b4d32SBaptiste Daroussin myfields[i].buf = malloc(items[i].maxvaluelen + 1); 391*263660c0SAlfonso Siciliano memset(myfields[i].buf, 0, items[i].maxvaluelen + 1); 392d93b4d32SBaptiste Daroussin strncpy(myfields[i].buf, items[i].init, items[i].maxvaluelen); 393d93b4d32SBaptiste Daroussin 394d93b4d32SBaptiste Daroussin myfields[i].buflen = strlen(myfields[i].buf); 395d93b4d32SBaptiste Daroussin 396d93b4d32SBaptiste Daroussin myfields[i].maxpos = items[i].maxvaluelen -1; 397d93b4d32SBaptiste Daroussin myfields[i].pos = MIN(myfields[i].buflen, myfields[i].maxpos); 398d93b4d32SBaptiste Daroussin 3998c4f4028SBaptiste Daroussin myfields[i].bottomdesc = items[i].bottomdesc; 400f499134dSBaptiste Daroussin set_field_userptr(cfield[i], &myfields[i]); 401f499134dSBaptiste Daroussin 402f499134dSBaptiste Daroussin field_opts_off(cfield[i], O_AUTOSKIP); 403f499134dSBaptiste Daroussin field_opts_off(cfield[i], O_BLANK); 404f499134dSBaptiste Daroussin 405f499134dSBaptiste Daroussin if (ISFIELDHIDDEN(items[i])) { 406f499134dSBaptiste Daroussin myfields[i].secure = true; 407f499134dSBaptiste Daroussin myfields[i].securech = ' '; 408f499134dSBaptiste Daroussin if (conf->form.securech != '\0') 409f499134dSBaptiste Daroussin myfields[i].securech = conf->form.securech; 410f499134dSBaptiste Daroussin } 411*263660c0SAlfonso Siciliano else 412*263660c0SAlfonso Siciliano myfields[i].secure = false; 413f499134dSBaptiste Daroussin 414f499134dSBaptiste Daroussin if (ISFIELDREADONLY(items[i])) { 415f499134dSBaptiste Daroussin field_opts_off(cfield[i], O_EDIT); 416f499134dSBaptiste Daroussin field_opts_off(cfield[i], O_ACTIVE); 417f499134dSBaptiste Daroussin color = t.form.readonlycolor; 418f499134dSBaptiste Daroussin } else { 419f499134dSBaptiste Daroussin color = i == 0 ? t.form.f_fieldcolor : t.form.fieldcolor; 420f499134dSBaptiste Daroussin } 421f499134dSBaptiste Daroussin set_field_fore(cfield[i], color); 422f499134dSBaptiste Daroussin set_field_back(cfield[i], color); 423f499134dSBaptiste Daroussin 424f499134dSBaptiste Daroussin maxline = MAX(maxline, items[i].xlabel + strlen(items[i].label)); 425*263660c0SAlfonso Siciliano maxline = MAX(maxline, items[i].xfield + items[i].fieldlen - 1); 426f499134dSBaptiste Daroussin } 427f499134dSBaptiste Daroussin cfield[i] = NULL; 428f499134dSBaptiste Daroussin 429f499134dSBaptiste Daroussin /* disable focus with 1 item (inputbox or passwordbox) */ 430f499134dSBaptiste Daroussin if (formheight == 1 && nitems == 1 && strlen(items[0].label) == 0 && 431f499134dSBaptiste Daroussin items[0].xfield == 1 ) { 4328c4f4028SBaptiste Daroussin set_field_fore(cfield[0], t.dialog.color); 4338c4f4028SBaptiste Daroussin set_field_back(cfield[0], t.dialog.color); 434f499134dSBaptiste Daroussin } 435c76f0793SBaptiste Daroussin 436*263660c0SAlfonso Siciliano get_buttons(conf, &bs, BUTTON_OK_LABEL, BUTTON_CANCEL_LABEL); 437c76f0793SBaptiste Daroussin 438f499134dSBaptiste Daroussin if (set_widget_size(conf, rows, cols, &h, &w) != 0) 439*263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 440*263660c0SAlfonso Siciliano if (form_autosize(conf, rows, cols, &h, &w, text, maxline, &formheight, 441*263660c0SAlfonso Siciliano nitems, bs) != 0) 442*263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 443*263660c0SAlfonso Siciliano if (form_checksize(h, w, text, formheight, nitems, maxline, bs) != 0) 444*263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 445f499134dSBaptiste Daroussin if (set_widget_position(conf, &y, &x, h, w) != 0) 446*263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 447c76f0793SBaptiste Daroussin 448*263660c0SAlfonso Siciliano if (new_dialog(conf, &shadow, &widget, y, x, h, w, &textpad, text, &bs, 449*263660c0SAlfonso Siciliano true) != 0) 450*263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 451c76f0793SBaptiste Daroussin 452*263660c0SAlfonso Siciliano prefresh(textpad, 0, 0, y + 1, x + 1 + TEXTHMARGIN, 453*263660c0SAlfonso Siciliano y + h - formheight, x + 1 + w - TEXTHMARGIN); 454c76f0793SBaptiste Daroussin 455f499134dSBaptiste Daroussin formwin = new_boxed_window(conf, y + h - 3 - formheight -2, x +1, 456f499134dSBaptiste Daroussin formheight+2, w-2, LOWERED); 457c76f0793SBaptiste Daroussin 458f499134dSBaptiste Daroussin form = new_form(cfield); 459f499134dSBaptiste Daroussin set_form_win(form, formwin); 460f499134dSBaptiste Daroussin /* should be formheight */ 461f499134dSBaptiste Daroussin set_form_sub(form, derwin(formwin, nitems, w-4, 1, 1)); 462c76f0793SBaptiste Daroussin post_form(form); 463c76f0793SBaptiste Daroussin 464f499134dSBaptiste Daroussin for (i = 0; i < (int)nitems; i++) 465*263660c0SAlfonso Siciliano mvwaddstr(formwin, items[i].ylabel, items[i].xlabel, 466*263660c0SAlfonso Siciliano items[i].label); 467c76f0793SBaptiste Daroussin 468f499134dSBaptiste Daroussin wrefresh(formwin); 469c76f0793SBaptiste Daroussin 470f499134dSBaptiste Daroussin do { 471*263660c0SAlfonso Siciliano output = form_handler(conf, widget, bs, formwin, form, cfield, 472*263660c0SAlfonso Siciliano nitems, items); 473f499134dSBaptiste Daroussin 474*263660c0SAlfonso Siciliano if (update_dialog(conf, shadow, widget, y, x, h, w, textpad, 475*263660c0SAlfonso Siciliano text, &bs, true) != 0) 476*263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 477f499134dSBaptiste Daroussin 478*263660c0SAlfonso Siciliano doupdate(); 479f499134dSBaptiste Daroussin wrefresh(widget); 480f499134dSBaptiste Daroussin 481*263660c0SAlfonso Siciliano prefresh(textpad, 0, 0, y + 1, x + 1 + TEXTHMARGIN, 482*263660c0SAlfonso Siciliano y + h - formheight, x + 1 + w - TEXTHMARGIN); 483f499134dSBaptiste Daroussin 484f499134dSBaptiste Daroussin draw_borders(conf, formwin, formheight+2, w-2, LOWERED); 485*263660c0SAlfonso Siciliano wrefresh(formwin); 486*263660c0SAlfonso Siciliano 487*263660c0SAlfonso Siciliano refresh(); 488f499134dSBaptiste Daroussin } while (output == REDRAWFORM); 489c76f0793SBaptiste Daroussin 490c76f0793SBaptiste Daroussin unpost_form(form); 491c76f0793SBaptiste Daroussin free_form(form); 492f499134dSBaptiste Daroussin for (i = 0; i < (int)nitems; i++) { 493f499134dSBaptiste Daroussin free_field(cfield[i]); 494f499134dSBaptiste Daroussin free(myfields[i].buf); 495f499134dSBaptiste Daroussin } 496f499134dSBaptiste Daroussin free(cfield); 497f499134dSBaptiste Daroussin free(myfields); 498c76f0793SBaptiste Daroussin 499f499134dSBaptiste Daroussin delwin(formwin); 500*263660c0SAlfonso Siciliano end_dialog(conf, shadow, widget, textpad); 501c76f0793SBaptiste Daroussin 502*263660c0SAlfonso Siciliano return (output); 503c76f0793SBaptiste Daroussin }