1c76f0793SBaptiste Daroussin /*- 2c76f0793SBaptiste Daroussin * SPDX-License-Identifier: BSD-2-Clause 3c76f0793SBaptiste Daroussin * 4263660c0SAlfonso 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 30d93b4d32SBaptiste Daroussin #include <ctype.h> 31263660c0SAlfonso Siciliano #include <curses.h> 32f499134dSBaptiste Daroussin #include <string.h> 33f499134dSBaptiste Daroussin 34c76f0793SBaptiste Daroussin #include "bsddialog.h" 35*b319d934SAlfonso S. Siciliano #include "bsddialog_theme.h" 36263660c0SAlfonso Siciliano #include "lib_util.h" 37c76f0793SBaptiste Daroussin 38263660c0SAlfonso Siciliano #define MINWDATE 23 /* 3 windows and their borders */ 39263660c0SAlfonso Siciliano #define MINWTIME 14 /* 3 windows and their borders */ 40f499134dSBaptiste Daroussin 41*b319d934SAlfonso S. Siciliano static void 42*b319d934SAlfonso S. Siciliano drawquare(struct bsddialog_conf *conf, WINDOW *win, const char *fmt, 43*b319d934SAlfonso S. Siciliano const void *value, bool focus) 44*b319d934SAlfonso S. Siciliano { 45*b319d934SAlfonso S. Siciliano int h, l, w; 46*b319d934SAlfonso S. Siciliano 47*b319d934SAlfonso S. Siciliano getmaxyx(win, h, w); 48*b319d934SAlfonso S. Siciliano draw_borders(conf, win, h, w, LOWERED); 49*b319d934SAlfonso S. Siciliano if (focus) { 50*b319d934SAlfonso S. Siciliano l = 2 + w%2; 51*b319d934SAlfonso S. Siciliano wattron(win, t.dialog.arrowcolor); 52*b319d934SAlfonso S. Siciliano mvwhline(win, 0, w/2 - l/2, 53*b319d934SAlfonso S. Siciliano conf->ascii_lines ? '^' : ACS_UARROW, l); 54*b319d934SAlfonso S. Siciliano mvwhline(win, h-1, w/2 - l/2, 55*b319d934SAlfonso S. Siciliano conf->ascii_lines ? 'v' : ACS_DARROW, l); 56*b319d934SAlfonso S. Siciliano wattroff(win, t.dialog.arrowcolor); 57*b319d934SAlfonso S. Siciliano } 58*b319d934SAlfonso S. Siciliano 59*b319d934SAlfonso S. Siciliano if (focus) 60*b319d934SAlfonso S. Siciliano wattron(win, t.menu.f_namecolor); 61*b319d934SAlfonso S. Siciliano if (strchr(fmt, 's') != NULL) 62*b319d934SAlfonso S. Siciliano mvwprintw(win, 1, 1, fmt, (const char*)value); 63*b319d934SAlfonso S. Siciliano else 64*b319d934SAlfonso S. Siciliano mvwprintw(win, 1, 1, fmt, *((const int*)value)); 65*b319d934SAlfonso S. Siciliano if (focus) 66*b319d934SAlfonso S. Siciliano wattroff(win, t.menu.f_namecolor); 67*b319d934SAlfonso S. Siciliano 68*b319d934SAlfonso S. Siciliano wrefresh(win); 69*b319d934SAlfonso S. Siciliano } 70*b319d934SAlfonso S. Siciliano 71f499134dSBaptiste Daroussin static int 72f499134dSBaptiste Daroussin datetime_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h, 73263660c0SAlfonso Siciliano int *w, int minw, const char *text, struct buttons bs) 74f499134dSBaptiste Daroussin { 75263660c0SAlfonso Siciliano int htext, wtext; 76f499134dSBaptiste Daroussin 77263660c0SAlfonso Siciliano if (cols == BSDDIALOG_AUTOSIZE || rows == BSDDIALOG_AUTOSIZE) { 78263660c0SAlfonso Siciliano if (text_size(conf, rows, cols, text, &bs, 3, minw, &htext, 79263660c0SAlfonso Siciliano &wtext) != 0) 80263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 81f499134dSBaptiste Daroussin } 82f499134dSBaptiste Daroussin 83263660c0SAlfonso Siciliano if (cols == BSDDIALOG_AUTOSIZE) 84*b319d934SAlfonso S. Siciliano *w = widget_min_width(conf, wtext, minw, &bs); 85f499134dSBaptiste Daroussin 86263660c0SAlfonso Siciliano if (rows == BSDDIALOG_AUTOSIZE) 87263660c0SAlfonso Siciliano *h = widget_min_height(conf, htext, 3 /* windows */, true); 88263660c0SAlfonso Siciliano 89263660c0SAlfonso Siciliano return (0); 90f499134dSBaptiste Daroussin } 91f499134dSBaptiste Daroussin 92f499134dSBaptiste Daroussin static int 93263660c0SAlfonso Siciliano datetime_checksize(int rows, int cols, int minw, struct buttons bs) 94f499134dSBaptiste Daroussin { 95f499134dSBaptiste Daroussin int mincols; 96f499134dSBaptiste Daroussin 97f499134dSBaptiste Daroussin mincols = VBORDERS; 98*b319d934SAlfonso S. Siciliano mincols += buttons_min_width(bs); 99f499134dSBaptiste Daroussin mincols = MAX(minw, mincols); 100f499134dSBaptiste Daroussin 101f499134dSBaptiste Daroussin if (cols < mincols) 102f499134dSBaptiste Daroussin RETURN_ERROR("Few cols for this timebox/datebox"); 103f499134dSBaptiste Daroussin 104263660c0SAlfonso Siciliano if (rows < 7) /* 2 button + 2 borders + 3 windows */ 105263660c0SAlfonso Siciliano RETURN_ERROR("Few rows for this timebox/datebox, at least 7"); 106f499134dSBaptiste Daroussin 107263660c0SAlfonso Siciliano return (0); 108f499134dSBaptiste Daroussin } 109f499134dSBaptiste Daroussin 110263660c0SAlfonso Siciliano int 111263660c0SAlfonso Siciliano bsddialog_timebox(struct bsddialog_conf *conf, const char* text, int rows, 112263660c0SAlfonso Siciliano int cols, unsigned int *hh, unsigned int *mm, unsigned int *ss) 113c76f0793SBaptiste Daroussin { 114bce40c02SAlfonso S. Siciliano bool loop, focusbuttons; 115*b319d934SAlfonso S. Siciliano int i, retval, y, x, h, w, sel; 116*b319d934SAlfonso S. Siciliano wint_t input; 117263660c0SAlfonso Siciliano WINDOW *widget, *textpad, *shadow; 118263660c0SAlfonso Siciliano struct buttons bs; 119c76f0793SBaptiste Daroussin struct myclockstruct { 120c76f0793SBaptiste Daroussin unsigned int max; 121f499134dSBaptiste Daroussin unsigned int value; 122c76f0793SBaptiste Daroussin WINDOW *win; 123f499134dSBaptiste Daroussin }; 124c76f0793SBaptiste Daroussin 125f499134dSBaptiste Daroussin if (hh == NULL || mm == NULL || ss == NULL) 126f499134dSBaptiste Daroussin RETURN_ERROR("hh / mm / ss cannot be NULL"); 127c76f0793SBaptiste Daroussin 128f499134dSBaptiste Daroussin struct myclockstruct c[3] = { 129f499134dSBaptiste Daroussin {23, *hh, NULL}, 130f499134dSBaptiste Daroussin {59, *mm, NULL}, 131f499134dSBaptiste Daroussin {59, *ss, NULL} 132f499134dSBaptiste Daroussin }; 133f499134dSBaptiste Daroussin 134f499134dSBaptiste Daroussin for (i = 0 ; i < 3; i++) { 135f499134dSBaptiste Daroussin if (c[i].value > c[i].max) 136f499134dSBaptiste Daroussin c[i].value = c[i].max; 137f499134dSBaptiste Daroussin } 138c76f0793SBaptiste Daroussin 139263660c0SAlfonso Siciliano get_buttons(conf, &bs, BUTTON_OK_LABEL, BUTTON_CANCEL_LABEL); 140c76f0793SBaptiste Daroussin 141f499134dSBaptiste Daroussin if (set_widget_size(conf, rows, cols, &h, &w) != 0) 142263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 143263660c0SAlfonso Siciliano if (datetime_autosize(conf, rows, cols, &h, &w, MINWTIME, text, 144263660c0SAlfonso Siciliano bs) != 0) 145263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 146263660c0SAlfonso Siciliano if (datetime_checksize(h, w, MINWTIME, bs) != 0) 147263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 148f499134dSBaptiste Daroussin if (set_widget_position(conf, &y, &x, h, w) != 0) 149263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 150f499134dSBaptiste Daroussin 151263660c0SAlfonso Siciliano if (new_dialog(conf, &shadow, &widget, y, x, h, w, &textpad, text, &bs, 152263660c0SAlfonso Siciliano true) != 0) 153263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 154f499134dSBaptiste Daroussin 155263660c0SAlfonso Siciliano pnoutrefresh(textpad, 0, 0, y+1, x+2, y+h-7, x+w-2); 156263660c0SAlfonso Siciliano doupdate(); 157f499134dSBaptiste Daroussin 158f499134dSBaptiste Daroussin c[0].win = new_boxed_window(conf, y+h-6, x + w/2 - 7, 3, 4, LOWERED); 159f499134dSBaptiste Daroussin mvwaddch(widget, h - 5, w/2 - 3, ':'); 160f499134dSBaptiste Daroussin c[1].win = new_boxed_window(conf, y+h-6, x + w/2 - 2, 3, 4, LOWERED); 161f499134dSBaptiste Daroussin mvwaddch(widget, h - 5, w/2 + 2, ':'); 162f499134dSBaptiste Daroussin c[2].win = new_boxed_window(conf, y+h-6, x + w/2 + 3, 3, 4, LOWERED); 163f499134dSBaptiste Daroussin 164f499134dSBaptiste Daroussin wrefresh(widget); 165f499134dSBaptiste Daroussin 166*b319d934SAlfonso S. Siciliano sel = -1; 167bce40c02SAlfonso S. Siciliano loop = focusbuttons = true; 168c76f0793SBaptiste Daroussin while (loop) { 169*b319d934SAlfonso S. Siciliano for (i = 0; i < 3; i++) 170*b319d934SAlfonso S. Siciliano drawquare(conf, c[i].win, "%02d", &c[i].value, 171*b319d934SAlfonso S. Siciliano sel == i); 172bce40c02SAlfonso S. Siciliano 173*b319d934SAlfonso S. Siciliano if (get_wch(&input) == ERR) 174*b319d934SAlfonso S. Siciliano continue; 175c76f0793SBaptiste Daroussin switch(input) { 176f499134dSBaptiste Daroussin case KEY_ENTER: 177c76f0793SBaptiste Daroussin case 10: /* Enter */ 178*b319d934SAlfonso S. Siciliano if (focusbuttons || conf->button.always_active) { 179*b319d934SAlfonso S. Siciliano retval = bs.value[bs.curr]; 180c76f0793SBaptiste Daroussin loop = false; 181*b319d934SAlfonso S. Siciliano } 182c76f0793SBaptiste Daroussin break; 183c76f0793SBaptiste Daroussin case 27: /* Esc */ 184263660c0SAlfonso Siciliano if (conf->key.enable_esc) { 185*b319d934SAlfonso S. Siciliano retval = BSDDIALOG_ESC; 186c76f0793SBaptiste Daroussin loop = false; 187263660c0SAlfonso Siciliano } 188c76f0793SBaptiste Daroussin break; 189bce40c02SAlfonso S. Siciliano case KEY_RIGHT: 190c76f0793SBaptiste Daroussin case '\t': /* TAB */ 191bce40c02SAlfonso S. Siciliano if (focusbuttons) { 192bce40c02SAlfonso S. Siciliano bs.curr++; 193bce40c02SAlfonso S. Siciliano focusbuttons = bs.curr < (int)bs.nbuttons ? 194bce40c02SAlfonso S. Siciliano true : false; 195bce40c02SAlfonso S. Siciliano if (focusbuttons == false) { 196bce40c02SAlfonso S. Siciliano sel = 0; 197*b319d934SAlfonso S. Siciliano bs.curr = conf->button.always_active ? 0 : -1; 198bce40c02SAlfonso S. Siciliano } 199bce40c02SAlfonso S. Siciliano } else { 200bce40c02SAlfonso S. Siciliano sel++; 201bce40c02SAlfonso S. Siciliano focusbuttons = sel > 2 ? true : false; 202bce40c02SAlfonso S. Siciliano if (focusbuttons) { 203bce40c02SAlfonso S. Siciliano bs.curr = 0; 204bce40c02SAlfonso S. Siciliano } 205bce40c02SAlfonso S. Siciliano } 206263660c0SAlfonso Siciliano draw_buttons(widget, bs, true); 207263660c0SAlfonso Siciliano wrefresh(widget); 208c76f0793SBaptiste Daroussin break; 209c76f0793SBaptiste Daroussin case KEY_LEFT: 210bce40c02SAlfonso S. Siciliano if (focusbuttons) { 211bce40c02SAlfonso S. Siciliano bs.curr--; 212bce40c02SAlfonso S. Siciliano focusbuttons = bs.curr < 0 ? false : true; 213bce40c02SAlfonso S. Siciliano if (focusbuttons == false) { 214bce40c02SAlfonso S. Siciliano sel = 2; 215*b319d934SAlfonso S. Siciliano bs.curr = conf->button.always_active ? 0 : -1; 216bce40c02SAlfonso S. Siciliano } 217bce40c02SAlfonso S. Siciliano } else { 218bce40c02SAlfonso S. Siciliano sel--; 219bce40c02SAlfonso S. Siciliano focusbuttons = sel < 0 ? true : false; 220*b319d934SAlfonso S. Siciliano if (focusbuttons) 221bce40c02SAlfonso S. Siciliano bs.curr = (int)bs.nbuttons - 1; 222bce40c02SAlfonso S. Siciliano } 223bce40c02SAlfonso S. Siciliano draw_buttons(widget, bs, true); 224bce40c02SAlfonso S. Siciliano wrefresh(widget); 225c76f0793SBaptiste Daroussin break; 226c76f0793SBaptiste Daroussin case KEY_UP: 227*b319d934SAlfonso S. Siciliano if (focusbuttons) { 228*b319d934SAlfonso S. Siciliano sel = 0; 229*b319d934SAlfonso S. Siciliano focusbuttons = false; 230*b319d934SAlfonso S. Siciliano bs.curr = conf->button.always_active ? 0 : -1; 231*b319d934SAlfonso S. Siciliano draw_buttons(widget, bs, true); 232*b319d934SAlfonso S. Siciliano wrefresh(widget); 233*b319d934SAlfonso S. Siciliano } else { c[sel].value = c[sel].value > 0 ? 234263660c0SAlfonso Siciliano c[sel].value - 1 : c[sel].max; 235*b319d934SAlfonso S. Siciliano } 236c76f0793SBaptiste Daroussin break; 237bce40c02SAlfonso S. Siciliano case KEY_DOWN: 238bce40c02SAlfonso S. Siciliano if (focusbuttons) 239bce40c02SAlfonso S. Siciliano break; 240bce40c02SAlfonso S. Siciliano c[sel].value = c[sel].value < c[sel].max ? 241bce40c02SAlfonso S. Siciliano c[sel].value + 1 : 0; 242bce40c02SAlfonso S. Siciliano break; 243f499134dSBaptiste Daroussin case KEY_F(1): 244bce40c02SAlfonso S. Siciliano if (conf->key.f1_file == NULL && 245bce40c02SAlfonso S. Siciliano conf->key.f1_message == NULL) 246f499134dSBaptiste Daroussin break; 247f499134dSBaptiste Daroussin if (f1help(conf) != 0) 248263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 249263660c0SAlfonso Siciliano /* No break, screen size can change */ 250f499134dSBaptiste Daroussin case KEY_RESIZE: 251263660c0SAlfonso Siciliano /* Important for decreasing screen */ 252f499134dSBaptiste Daroussin hide_widget(y, x, h, w, conf->shadow); 253f499134dSBaptiste Daroussin refresh(); 254f499134dSBaptiste Daroussin 255f499134dSBaptiste Daroussin if (set_widget_size(conf, rows, cols, &h, &w) != 0) 256263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 257263660c0SAlfonso Siciliano if (datetime_autosize(conf, rows, cols, &h, &w, 258263660c0SAlfonso Siciliano MINWTIME, text, bs) != 0) 259263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 260263660c0SAlfonso Siciliano if (datetime_checksize(h, w, MINWTIME, bs) != 0) 261263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 262f499134dSBaptiste Daroussin if (set_widget_position(conf, &y, &x, h, w) != 0) 263263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 264f499134dSBaptiste Daroussin 265263660c0SAlfonso Siciliano if (update_dialog(conf, shadow, widget, y, x, h, w, 266263660c0SAlfonso Siciliano textpad, text, &bs, true) != 0) 267263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 268f499134dSBaptiste Daroussin 269263660c0SAlfonso Siciliano doupdate(); 270f499134dSBaptiste Daroussin 271f499134dSBaptiste Daroussin mvwaddch(widget, h - 5, w/2 - 3, ':'); 272f499134dSBaptiste Daroussin mvwaddch(widget, h - 5, w/2 + 2, ':'); 273f499134dSBaptiste Daroussin wrefresh(widget); 274f499134dSBaptiste Daroussin 275f499134dSBaptiste Daroussin prefresh(textpad, 0, 0, y+1, x+2, y+h-7, x+w-2); 276f499134dSBaptiste Daroussin 277f499134dSBaptiste Daroussin wclear(c[0].win); 278f499134dSBaptiste Daroussin mvwin(c[0].win, y + h - 6, x + w/2 - 7); 279f499134dSBaptiste Daroussin wclear(c[1].win); 280f499134dSBaptiste Daroussin mvwin(c[1].win, y + h - 6, x + w/2 - 2); 281f499134dSBaptiste Daroussin wclear(c[2].win); 282f499134dSBaptiste Daroussin mvwin(c[2].win, y + h - 6, x + w/2 + 3); 283f499134dSBaptiste Daroussin 284f499134dSBaptiste Daroussin /* Important to avoid grey lines expanding screen */ 285f499134dSBaptiste Daroussin refresh(); 286f499134dSBaptiste Daroussin break; 287f499134dSBaptiste Daroussin default: 288263660c0SAlfonso Siciliano if (shortcut_buttons(input, &bs)) { 289*b319d934SAlfonso S. Siciliano retval = bs.value[bs.curr]; 290f499134dSBaptiste Daroussin loop = false; 291f499134dSBaptiste Daroussin } 292c76f0793SBaptiste Daroussin } 293c76f0793SBaptiste Daroussin } 294c76f0793SBaptiste Daroussin 295*b319d934SAlfonso S. Siciliano if (retval == BSDDIALOG_OK) { 296bce40c02SAlfonso S. Siciliano *hh = c[0].value; 297bce40c02SAlfonso S. Siciliano *mm = c[1].value; 298bce40c02SAlfonso S. Siciliano *ss = c[2].value; 299bce40c02SAlfonso S. Siciliano } 300bce40c02SAlfonso S. Siciliano 301c76f0793SBaptiste Daroussin for (i = 0; i < 3; i++) 302c76f0793SBaptiste Daroussin delwin(c[i].win); 303263660c0SAlfonso Siciliano end_dialog(conf, shadow, widget, textpad); 304c76f0793SBaptiste Daroussin 305*b319d934SAlfonso S. Siciliano return (retval); 306c76f0793SBaptiste Daroussin } 307c76f0793SBaptiste Daroussin 308f499134dSBaptiste Daroussin int 309263660c0SAlfonso Siciliano bsddialog_datebox(struct bsddialog_conf *conf, const char *text, int rows, 310263660c0SAlfonso Siciliano int cols, unsigned int *yy, unsigned int *mm, unsigned int *dd) 311c76f0793SBaptiste Daroussin { 312bce40c02SAlfonso S. Siciliano bool loop, focusbuttons; 313*b319d934SAlfonso S. Siciliano int i, retval, y, x, h, w, sel; 314*b319d934SAlfonso S. Siciliano wint_t input; 315263660c0SAlfonso Siciliano WINDOW *widget, *textpad, *shadow; 316263660c0SAlfonso Siciliano struct buttons bs; 317c76f0793SBaptiste Daroussin struct calendar { 318f499134dSBaptiste Daroussin int max; 319f499134dSBaptiste Daroussin int value; 320c76f0793SBaptiste Daroussin WINDOW *win; 321c76f0793SBaptiste Daroussin unsigned int x; 322f499134dSBaptiste Daroussin }; 323c76f0793SBaptiste Daroussin struct month { 324bce40c02SAlfonso S. Siciliano const char *name; 325c76f0793SBaptiste Daroussin unsigned int days; 326c76f0793SBaptiste Daroussin }; 327c76f0793SBaptiste Daroussin 328f499134dSBaptiste Daroussin if (yy == NULL || mm == NULL || dd == NULL) 329f499134dSBaptiste Daroussin RETURN_ERROR("yy / mm / dd cannot be NULL"); 330c76f0793SBaptiste Daroussin 331f499134dSBaptiste Daroussin struct calendar c[3] = { 332f499134dSBaptiste Daroussin {9999, *yy, NULL, 4 }, 333f499134dSBaptiste Daroussin {12, *mm, NULL, 9 }, 334f499134dSBaptiste Daroussin {31, *dd, NULL, 2 } 335f499134dSBaptiste Daroussin }; 336c76f0793SBaptiste Daroussin 337f499134dSBaptiste Daroussin struct month m[12] = { 338f499134dSBaptiste Daroussin { "January", 31 }, { "February", 28 }, { "March", 31 }, 339f499134dSBaptiste Daroussin { "April", 30 }, { "May", 31 }, { "June", 30 }, 340f499134dSBaptiste Daroussin { "July", 31 }, { "August", 31 }, { "September", 30 }, 341f499134dSBaptiste Daroussin { "October", 31 }, { "November", 30 }, { "December", 31 } 342f499134dSBaptiste Daroussin }; 343f499134dSBaptiste Daroussin 344f499134dSBaptiste Daroussin #define ISLEAF(year) ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) 345f499134dSBaptiste Daroussin 346f499134dSBaptiste Daroussin for (i = 0 ; i < 3; i++) { 347f499134dSBaptiste Daroussin if (c[i].value > c[i].max) 348f499134dSBaptiste Daroussin c[i].value = c[i].max; 349f499134dSBaptiste Daroussin if (c[i].value < 1) 350f499134dSBaptiste Daroussin c[i].value = 1; 351f499134dSBaptiste Daroussin } 352f499134dSBaptiste Daroussin c[2].max = m[c[1].value -1].days; 353f499134dSBaptiste Daroussin if (c[1].value == 2 && ISLEAF(c[0].value)) 354f499134dSBaptiste Daroussin c[2].max = 29; 355f499134dSBaptiste Daroussin if (c[2].value > c[2].max) 356f499134dSBaptiste Daroussin c[2].value = c[2].max; 357c76f0793SBaptiste Daroussin 358263660c0SAlfonso Siciliano get_buttons(conf, &bs, BUTTON_OK_LABEL, BUTTON_CANCEL_LABEL); 359c76f0793SBaptiste Daroussin 360f499134dSBaptiste Daroussin if (set_widget_size(conf, rows, cols, &h, &w) != 0) 361263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 362263660c0SAlfonso Siciliano if (datetime_autosize(conf, rows, cols, &h, &w, MINWDATE, text, 363263660c0SAlfonso Siciliano bs) != 0) 364263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 365263660c0SAlfonso Siciliano if (datetime_checksize(h, w, MINWDATE, bs) != 0) 366263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 367f499134dSBaptiste Daroussin if (set_widget_position(conf, &y, &x, h, w) != 0) 368263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 369f499134dSBaptiste Daroussin 370263660c0SAlfonso Siciliano if (new_dialog(conf, &shadow, &widget, y, x, h, w, &textpad, text, &bs, 371263660c0SAlfonso Siciliano true) != 0) 372263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 373f499134dSBaptiste Daroussin 374263660c0SAlfonso Siciliano pnoutrefresh(textpad, 0, 0, y+1, x+2, y+h-7, x+w-2); 375263660c0SAlfonso Siciliano doupdate(); 376f499134dSBaptiste Daroussin 377f499134dSBaptiste Daroussin c[0].win = new_boxed_window(conf, y+h-6, x + w/2 - 11, 3, 6, LOWERED); 378f499134dSBaptiste Daroussin mvwaddch(widget, h - 5, w/2 - 5, '/'); 379f499134dSBaptiste Daroussin c[1].win = new_boxed_window(conf, y+h-6, x + w/2 - 4, 3, 11, LOWERED); 380f499134dSBaptiste Daroussin mvwaddch(widget, h - 5, w/2 + 7, '/'); 381f499134dSBaptiste Daroussin c[2].win = new_boxed_window(conf, y+h-6, x + w/2 + 8, 3, 4, LOWERED); 382f499134dSBaptiste Daroussin 383f499134dSBaptiste Daroussin wrefresh(widget); 384f499134dSBaptiste Daroussin 385*b319d934SAlfonso S. Siciliano sel = -1; 386bce40c02SAlfonso S. Siciliano loop = focusbuttons = true; 387c76f0793SBaptiste Daroussin while (loop) { 388*b319d934SAlfonso S. Siciliano drawquare(conf, c[0].win, "%4d", &c[0].value, sel == 0); 389*b319d934SAlfonso S. Siciliano drawquare(conf, c[1].win, "%9s", m[c[1].value-1].name, 390*b319d934SAlfonso S. Siciliano sel == 1); 391*b319d934SAlfonso S. Siciliano drawquare(conf, c[2].win, "%02d", &c[2].value, sel == 2); 392c76f0793SBaptiste Daroussin 393*b319d934SAlfonso S. Siciliano if (get_wch(&input) == ERR) 394*b319d934SAlfonso S. Siciliano continue; 395c76f0793SBaptiste Daroussin switch(input) { 396f499134dSBaptiste Daroussin case KEY_ENTER: 397f499134dSBaptiste Daroussin case 10: /* Enter */ 398*b319d934SAlfonso S. Siciliano if (focusbuttons || conf->button.always_active) { 399*b319d934SAlfonso S. Siciliano retval = bs.value[bs.curr]; 400c76f0793SBaptiste Daroussin loop = false; 401*b319d934SAlfonso S. Siciliano } 402c76f0793SBaptiste Daroussin break; 403f499134dSBaptiste Daroussin case 27: /* Esc */ 404263660c0SAlfonso Siciliano if (conf->key.enable_esc) { 405*b319d934SAlfonso S. Siciliano retval = BSDDIALOG_ESC; 406c76f0793SBaptiste Daroussin loop = false; 407263660c0SAlfonso Siciliano } 408c76f0793SBaptiste Daroussin break; 409bce40c02SAlfonso S. Siciliano case KEY_RIGHT: 410f499134dSBaptiste Daroussin case '\t': /* TAB */ 411bce40c02SAlfonso S. Siciliano if (focusbuttons) { 412bce40c02SAlfonso S. Siciliano bs.curr++; 413bce40c02SAlfonso S. Siciliano focusbuttons = bs.curr < (int)bs.nbuttons ? 414bce40c02SAlfonso S. Siciliano true : false; 415bce40c02SAlfonso S. Siciliano if (focusbuttons == false) { 416bce40c02SAlfonso S. Siciliano sel = 0; 417*b319d934SAlfonso S. Siciliano bs.curr = conf->button.always_active ? 0 : -1; 418bce40c02SAlfonso S. Siciliano } 419bce40c02SAlfonso S. Siciliano } else { 420bce40c02SAlfonso S. Siciliano sel++; 421bce40c02SAlfonso S. Siciliano focusbuttons = sel > 2 ? true : false; 422bce40c02SAlfonso S. Siciliano if (focusbuttons) { 423bce40c02SAlfonso S. Siciliano bs.curr = 0; 424bce40c02SAlfonso S. Siciliano } 425bce40c02SAlfonso S. Siciliano } 426263660c0SAlfonso Siciliano draw_buttons(widget, bs, true); 427263660c0SAlfonso Siciliano wrefresh(widget); 428c76f0793SBaptiste Daroussin break; 429c76f0793SBaptiste Daroussin case KEY_LEFT: 430bce40c02SAlfonso S. Siciliano if (focusbuttons) { 431bce40c02SAlfonso S. Siciliano bs.curr--; 432bce40c02SAlfonso S. Siciliano focusbuttons = bs.curr < 0 ? false : true; 433bce40c02SAlfonso S. Siciliano if (focusbuttons == false) { 434bce40c02SAlfonso S. Siciliano sel = 2; 435*b319d934SAlfonso S. Siciliano bs.curr = conf->button.always_active ? 0 : -1; 436bce40c02SAlfonso S. Siciliano } 437bce40c02SAlfonso S. Siciliano } else { 438bce40c02SAlfonso S. Siciliano sel--; 439bce40c02SAlfonso S. Siciliano focusbuttons = sel < 0 ? true : false; 440*b319d934SAlfonso S. Siciliano if (focusbuttons) 441bce40c02SAlfonso S. Siciliano bs.curr = (int)bs.nbuttons - 1; 442bce40c02SAlfonso S. Siciliano } 443bce40c02SAlfonso S. Siciliano draw_buttons(widget, bs, true); 444bce40c02SAlfonso S. Siciliano wrefresh(widget); 445c76f0793SBaptiste Daroussin break; 446c76f0793SBaptiste Daroussin case KEY_UP: 447*b319d934SAlfonso S. Siciliano if (focusbuttons) { 448*b319d934SAlfonso S. Siciliano sel = 0; 449*b319d934SAlfonso S. Siciliano focusbuttons = false; 450*b319d934SAlfonso S. Siciliano bs.curr = conf->button.always_active ? 0 : -1; 451*b319d934SAlfonso S. Siciliano draw_buttons(widget, bs, true); 452*b319d934SAlfonso S. Siciliano wrefresh(widget); 453*b319d934SAlfonso S. Siciliano } else { 454263660c0SAlfonso Siciliano c[sel].value = c[sel].value > 1 ? 455263660c0SAlfonso Siciliano c[sel].value - 1 : c[sel].max ; 456f499134dSBaptiste Daroussin /* if mount change */ 457f499134dSBaptiste Daroussin c[2].max = m[c[1].value -1].days; 458f499134dSBaptiste Daroussin /* if year change */ 459f499134dSBaptiste Daroussin if (c[1].value == 2 && ISLEAF(c[0].value)) 460f499134dSBaptiste Daroussin c[2].max = 29; 461f499134dSBaptiste Daroussin /* set new day */ 462f499134dSBaptiste Daroussin if (c[2].value > c[2].max) 463f499134dSBaptiste Daroussin c[2].value = c[2].max; 464*b319d934SAlfonso S. Siciliano } 465c76f0793SBaptiste Daroussin break; 466c76f0793SBaptiste Daroussin case KEY_DOWN: 467bce40c02SAlfonso S. Siciliano if (focusbuttons) 468bce40c02SAlfonso S. Siciliano break; 469263660c0SAlfonso Siciliano c[sel].value = c[sel].value < c[sel].max ? 470263660c0SAlfonso Siciliano c[sel].value + 1 : 1; 471f499134dSBaptiste Daroussin /* if mount change */ 472f499134dSBaptiste Daroussin c[2].max = m[c[1].value -1].days; 473f499134dSBaptiste Daroussin /* if year change */ 474f499134dSBaptiste Daroussin if (c[1].value == 2 && ISLEAF(c[0].value)) 475f499134dSBaptiste Daroussin c[2].max = 29; 476f499134dSBaptiste Daroussin /* set new day */ 477f499134dSBaptiste Daroussin if (c[2].value > c[2].max) 478f499134dSBaptiste Daroussin c[2].value = c[2].max; 479c76f0793SBaptiste Daroussin break; 480f499134dSBaptiste Daroussin case KEY_F(1): 481bce40c02SAlfonso S. Siciliano if (conf->key.f1_file == NULL && 482bce40c02SAlfonso S. Siciliano conf->key.f1_message == NULL) 483f499134dSBaptiste Daroussin break; 484f499134dSBaptiste Daroussin if (f1help(conf) != 0) 485263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 486263660c0SAlfonso Siciliano /* No break, screen size can change */ 487f499134dSBaptiste Daroussin case KEY_RESIZE: 488263660c0SAlfonso Siciliano /* Important for decreasing screen */ 489f499134dSBaptiste Daroussin hide_widget(y, x, h, w, conf->shadow); 490f499134dSBaptiste Daroussin refresh(); 491f499134dSBaptiste Daroussin 492f499134dSBaptiste Daroussin if (set_widget_size(conf, rows, cols, &h, &w) != 0) 493263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 494263660c0SAlfonso Siciliano if (datetime_autosize(conf, rows, cols, &h, &w, 495263660c0SAlfonso Siciliano MINWDATE, text, bs) != 0) 496263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 497263660c0SAlfonso Siciliano if (datetime_checksize(h, w, MINWDATE, bs) != 0) 498263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 499f499134dSBaptiste Daroussin if (set_widget_position(conf, &y, &x, h, w) != 0) 500263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 501f499134dSBaptiste Daroussin 502263660c0SAlfonso Siciliano if (update_dialog(conf, shadow, widget, y, x, h, w, 503263660c0SAlfonso Siciliano textpad, text, &bs, true) != 0) 504263660c0SAlfonso Siciliano return (BSDDIALOG_ERROR); 505263660c0SAlfonso Siciliano doupdate(); 506f499134dSBaptiste Daroussin 507f499134dSBaptiste Daroussin mvwaddch(widget, h - 5, w/2 - 5, '/'); 508f499134dSBaptiste Daroussin mvwaddch(widget, h - 5, w/2 + 7, '/'); 509f499134dSBaptiste Daroussin wrefresh(widget); 510f499134dSBaptiste Daroussin 511f499134dSBaptiste Daroussin prefresh(textpad, 0, 0, y+1, x+2, y+h-7, x+w-2); 512f499134dSBaptiste Daroussin 513f499134dSBaptiste Daroussin wclear(c[0].win); 514f499134dSBaptiste Daroussin mvwin(c[0].win, y + h - 6, x + w/2 - 11); 515f499134dSBaptiste Daroussin wclear(c[1].win); 516f499134dSBaptiste Daroussin mvwin(c[1].win, y + h - 6, x + w/2 - 4); 517f499134dSBaptiste Daroussin wclear(c[2].win); 518f499134dSBaptiste Daroussin mvwin(c[2].win, y + h - 6, x + w/2 + 8); 519f499134dSBaptiste Daroussin 520f499134dSBaptiste Daroussin /* Important to avoid grey lines expanding screen */ 521f499134dSBaptiste Daroussin refresh(); 522f499134dSBaptiste Daroussin break; 523f499134dSBaptiste Daroussin default: 524263660c0SAlfonso Siciliano if (shortcut_buttons(input, &bs)) { 525*b319d934SAlfonso S. Siciliano retval = bs.value[bs.curr]; 526f499134dSBaptiste Daroussin loop = false; 527f499134dSBaptiste Daroussin } 528c76f0793SBaptiste Daroussin } 529c76f0793SBaptiste Daroussin } 530c76f0793SBaptiste Daroussin 531*b319d934SAlfonso S. Siciliano if (retval == BSDDIALOG_OK) { 532bce40c02SAlfonso S. Siciliano *yy = c[0].value; 533bce40c02SAlfonso S. Siciliano *mm = c[1].value; 534bce40c02SAlfonso S. Siciliano *dd = c[2].value; 535bce40c02SAlfonso S. Siciliano } 536bce40c02SAlfonso S. Siciliano 537c76f0793SBaptiste Daroussin for (i = 0; i < 3; i++) 538c76f0793SBaptiste Daroussin delwin(c[i].win); 539263660c0SAlfonso Siciliano end_dialog(conf, shadow, widget, textpad); 540c76f0793SBaptiste Daroussin 541*b319d934SAlfonso S. Siciliano return (retval); 542c76f0793SBaptiste Daroussin } 543