1c76f0793SBaptiste Daroussin /*- 2c76f0793SBaptiste Daroussin * SPDX-License-Identifier: BSD-2-Clause 3c76f0793SBaptiste Daroussin * 4c76f0793SBaptiste Daroussin * Copyright (c) 2021 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 30*d93b4d32SBaptiste Daroussin #include <ctype.h> 31c76f0793SBaptiste Daroussin #ifdef PORTNCURSES 328c4f4028SBaptiste Daroussin #include <ncurses/ncurses.h> 33c76f0793SBaptiste Daroussin #else 348c4f4028SBaptiste Daroussin #include <ncurses.h> 35c76f0793SBaptiste Daroussin #endif 36f499134dSBaptiste Daroussin #include <string.h> 37f499134dSBaptiste Daroussin 38c76f0793SBaptiste Daroussin #include "bsddialog.h" 39c76f0793SBaptiste Daroussin #include "lib_util.h" 40f499134dSBaptiste Daroussin #include "bsddialog_theme.h" 41c76f0793SBaptiste Daroussin 42f499134dSBaptiste Daroussin #define MINWDATE 25 /* 23 wins + 2 VBORDERS */ 43f499134dSBaptiste Daroussin #define MINWTIME 16 /*14 wins + 2 VBORDERS */ 44f499134dSBaptiste Daroussin #define MINHEIGHT 8 /* 2 for text */ 45c76f0793SBaptiste Daroussin 46f499134dSBaptiste Daroussin /* "Time": timebox - datebox */ 47f499134dSBaptiste Daroussin 48f499134dSBaptiste Daroussin extern struct bsddialog_theme t; 49f499134dSBaptiste Daroussin 50f499134dSBaptiste Daroussin static int 51f499134dSBaptiste Daroussin datetime_autosize(struct bsddialog_conf *conf, int rows, int cols, int *h, 52f499134dSBaptiste Daroussin int *w, int minw, char *text, struct buttons bs) 53f499134dSBaptiste Daroussin { 54f499134dSBaptiste Daroussin int maxword, maxline, nlines, line; 55f499134dSBaptiste Daroussin 56f499134dSBaptiste Daroussin if (get_text_properties(conf, text, &maxword, &maxline, &nlines) != 0) 57f499134dSBaptiste Daroussin return BSDDIALOG_ERROR; 58f499134dSBaptiste Daroussin 59f499134dSBaptiste Daroussin if (cols == BSDDIALOG_AUTOSIZE) { 60f499134dSBaptiste Daroussin *w = VBORDERS; 61f499134dSBaptiste Daroussin /* buttons size */ 62f499134dSBaptiste Daroussin *w += bs.nbuttons * bs.sizebutton; 63f499134dSBaptiste Daroussin *w += bs.nbuttons > 0 ? (bs.nbuttons-1) * t.button.space : 0; 64f499134dSBaptiste Daroussin /* text size */ 65f499134dSBaptiste Daroussin line = maxline + VBORDERS + t.text.hmargin * 2; 66f499134dSBaptiste Daroussin line = MAX(line, (int) (maxword + VBORDERS + t.text.hmargin * 2)); 67f499134dSBaptiste Daroussin *w = MAX(*w, line); 68f499134dSBaptiste Daroussin /* date windows */ 69f499134dSBaptiste Daroussin *w = MAX(*w, minw); 708c4f4028SBaptiste Daroussin /* conf.auto_minwidth */ 718c4f4028SBaptiste Daroussin *w = MAX(*w, (int)conf->auto_minwidth); 72f499134dSBaptiste Daroussin /* avoid terminal overflow */ 73f499134dSBaptiste Daroussin *w = MIN(*w, widget_max_width(conf) -1); 74f499134dSBaptiste Daroussin } 75f499134dSBaptiste Daroussin 76f499134dSBaptiste Daroussin if (rows == BSDDIALOG_AUTOSIZE) { 77f499134dSBaptiste Daroussin *h = MINHEIGHT; 78f499134dSBaptiste Daroussin if (maxword > 0) 798c4f4028SBaptiste Daroussin *h += MAX(nlines, (int)(*w / GET_ASPECT_RATIO(conf))); 808c4f4028SBaptiste Daroussin /* conf.auto_minheight */ 818c4f4028SBaptiste Daroussin *h = MAX(*h, (int)conf->auto_minheight); 82f499134dSBaptiste Daroussin /* avoid terminal overflow */ 83f499134dSBaptiste Daroussin *h = MIN(*h, widget_max_height(conf) -1); 84f499134dSBaptiste Daroussin } 85f499134dSBaptiste Daroussin 86f499134dSBaptiste Daroussin return 0; 87f499134dSBaptiste Daroussin } 88f499134dSBaptiste Daroussin 89f499134dSBaptiste Daroussin static int 90f499134dSBaptiste Daroussin datetime_checksize(int rows, int cols, char *text, int minw, struct buttons bs) 91f499134dSBaptiste Daroussin { 92f499134dSBaptiste Daroussin int mincols; 93f499134dSBaptiste Daroussin 94f499134dSBaptiste Daroussin mincols = VBORDERS; 95f499134dSBaptiste Daroussin mincols += bs.nbuttons * bs.sizebutton; 96f499134dSBaptiste Daroussin mincols += bs.nbuttons > 0 ? (bs.nbuttons-1) * t.button.space : 0; 97f499134dSBaptiste Daroussin mincols = MAX(minw, mincols); 98f499134dSBaptiste Daroussin 99f499134dSBaptiste Daroussin if (cols < mincols) 100f499134dSBaptiste Daroussin RETURN_ERROR("Few cols for this timebox/datebox"); 101f499134dSBaptiste Daroussin 102f499134dSBaptiste Daroussin if (rows < MINHEIGHT + (strlen(text) > 0 ? 1 : 0)) 103f499134dSBaptiste Daroussin RETURN_ERROR("Few rows for this timebox/datebox"); 104f499134dSBaptiste Daroussin 105f499134dSBaptiste Daroussin return 0; 106f499134dSBaptiste Daroussin } 107f499134dSBaptiste Daroussin 108f499134dSBaptiste Daroussin int bsddialog_timebox(struct bsddialog_conf *conf, char* text, int rows, int cols, 109c76f0793SBaptiste Daroussin unsigned int *hh, unsigned int *mm, unsigned int *ss) 110c76f0793SBaptiste Daroussin { 111f499134dSBaptiste Daroussin WINDOW *widget, *textpad, *shadow; 112f499134dSBaptiste Daroussin int i, input, output, y, x, h, w, sel, htextpad; 113c76f0793SBaptiste Daroussin struct buttons bs; 114f499134dSBaptiste Daroussin bool loop; 115c76f0793SBaptiste Daroussin struct myclockstruct { 116c76f0793SBaptiste Daroussin unsigned int max; 117f499134dSBaptiste Daroussin unsigned int value; 118c76f0793SBaptiste Daroussin WINDOW *win; 119f499134dSBaptiste Daroussin }; 120c76f0793SBaptiste Daroussin 121f499134dSBaptiste Daroussin if (hh == NULL || mm == NULL || ss == NULL) 122f499134dSBaptiste Daroussin RETURN_ERROR("hh / mm / ss cannot be NULL"); 123c76f0793SBaptiste Daroussin 124f499134dSBaptiste Daroussin struct myclockstruct c[3] = { 125f499134dSBaptiste Daroussin {23, *hh, NULL}, 126f499134dSBaptiste Daroussin {59, *mm, NULL}, 127f499134dSBaptiste Daroussin {59, *ss, NULL} 128f499134dSBaptiste Daroussin }; 129f499134dSBaptiste Daroussin 130f499134dSBaptiste Daroussin for (i = 0 ; i < 3; i++) { 131f499134dSBaptiste Daroussin if (c[i].value > c[i].max) 132f499134dSBaptiste Daroussin c[i].value = c[i].max; 133f499134dSBaptiste Daroussin } 134c76f0793SBaptiste Daroussin 135c76f0793SBaptiste Daroussin get_buttons(conf, &bs, BUTTONLABEL(ok_label), BUTTONLABEL(extra_label), 136c76f0793SBaptiste Daroussin BUTTONLABEL(cancel_label), BUTTONLABEL(help_label)); 137c76f0793SBaptiste Daroussin 138f499134dSBaptiste Daroussin if (set_widget_size(conf, rows, cols, &h, &w) != 0) 139f499134dSBaptiste Daroussin return BSDDIALOG_ERROR; 140f499134dSBaptiste Daroussin if (datetime_autosize(conf, rows, cols, &h, &w, MINWTIME, text, bs) != 0) 141f499134dSBaptiste Daroussin return BSDDIALOG_ERROR; 142f499134dSBaptiste Daroussin if (datetime_checksize(h, w, text, MINWTIME, bs) != 0) 143f499134dSBaptiste Daroussin return BSDDIALOG_ERROR; 144f499134dSBaptiste Daroussin if (set_widget_position(conf, &y, &x, h, w) != 0) 145f499134dSBaptiste Daroussin return BSDDIALOG_ERROR; 146f499134dSBaptiste Daroussin 147f499134dSBaptiste Daroussin if (new_widget_withtextpad(conf, &shadow, &widget, y, x, h, w, RAISED, 148f499134dSBaptiste Daroussin &textpad, &htextpad, text, true) != 0) 149f499134dSBaptiste Daroussin return BSDDIALOG_ERROR; 150f499134dSBaptiste Daroussin 151f499134dSBaptiste Daroussin draw_buttons(widget, h-2, w, bs, true); 152f499134dSBaptiste Daroussin 153f499134dSBaptiste Daroussin wrefresh(widget); 154f499134dSBaptiste Daroussin 155f499134dSBaptiste Daroussin prefresh(textpad, 0, 0, y+1, x+2, y+h-7, x+w-2); 156f499134dSBaptiste Daroussin 157f499134dSBaptiste Daroussin c[0].win = new_boxed_window(conf, y + h - 6, x + w/2 - 7, 3, 4, LOWERED); 158f499134dSBaptiste Daroussin mvwaddch(widget, h - 5, w/2 - 3, ':'); 159f499134dSBaptiste Daroussin c[1].win = new_boxed_window(conf, y + h - 6, x + w/2 - 2, 3, 4, LOWERED); 160f499134dSBaptiste Daroussin mvwaddch(widget, h - 5, w/2 + 2, ':'); 161f499134dSBaptiste Daroussin c[2].win = new_boxed_window(conf, y + h - 6, x + w/2 + 3, 3, 4, LOWERED); 162f499134dSBaptiste Daroussin 163f499134dSBaptiste Daroussin wrefresh(widget); 164f499134dSBaptiste Daroussin 165c76f0793SBaptiste Daroussin sel = 0; 166c76f0793SBaptiste Daroussin curs_set(2); 167f499134dSBaptiste Daroussin loop = true; 168c76f0793SBaptiste Daroussin while(loop) { 169c76f0793SBaptiste Daroussin for (i=0; i<3; i++) { 170f499134dSBaptiste Daroussin mvwprintw(c[i].win, 1, 1, "%2d", c[i].value); 171c76f0793SBaptiste Daroussin wrefresh(c[i].win); 172c76f0793SBaptiste Daroussin } 173c76f0793SBaptiste Daroussin wmove(c[sel].win, 1, 2); 174c76f0793SBaptiste Daroussin wrefresh(c[sel].win); 175c76f0793SBaptiste Daroussin 176c76f0793SBaptiste Daroussin input = getch(); 177c76f0793SBaptiste Daroussin switch(input) { 178f499134dSBaptiste Daroussin case KEY_ENTER: 179c76f0793SBaptiste Daroussin case 10: /* Enter */ 180c76f0793SBaptiste Daroussin output = bs.value[bs.curr]; 1818c4f4028SBaptiste Daroussin if (output == BSDDIALOG_OK) { 182f499134dSBaptiste Daroussin *hh = c[0].value; 183f499134dSBaptiste Daroussin *mm = c[1].value; 184f499134dSBaptiste Daroussin *ss = c[2].value; 185c76f0793SBaptiste Daroussin } 186c76f0793SBaptiste Daroussin loop = false; 187c76f0793SBaptiste Daroussin break; 188c76f0793SBaptiste Daroussin case 27: /* Esc */ 189c76f0793SBaptiste Daroussin output = BSDDIALOG_ESC; 190c76f0793SBaptiste Daroussin loop = false; 191c76f0793SBaptiste Daroussin break; 192c76f0793SBaptiste Daroussin case '\t': /* TAB */ 193c76f0793SBaptiste Daroussin sel = (sel + 1) % 3; 194c76f0793SBaptiste Daroussin break; 195c76f0793SBaptiste Daroussin case KEY_LEFT: 196c76f0793SBaptiste Daroussin if (bs.curr > 0) { 197c76f0793SBaptiste Daroussin bs.curr--; 198f499134dSBaptiste Daroussin draw_buttons(widget, h-2, w, bs, true); 199f499134dSBaptiste Daroussin wrefresh(widget); 200c76f0793SBaptiste Daroussin } 201c76f0793SBaptiste Daroussin break; 202c76f0793SBaptiste Daroussin case KEY_RIGHT: 203c76f0793SBaptiste Daroussin if (bs.curr < (int) bs.nbuttons - 1) { 204c76f0793SBaptiste Daroussin bs.curr++; 205f499134dSBaptiste Daroussin draw_buttons(widget, h-2, w, bs, true); 206f499134dSBaptiste Daroussin wrefresh(widget); 207c76f0793SBaptiste Daroussin } 208c76f0793SBaptiste Daroussin break; 209c76f0793SBaptiste Daroussin case KEY_UP: 210f499134dSBaptiste Daroussin c[sel].value = c[sel].value < c[sel].max ? c[sel].value + 1 : 0; 211c76f0793SBaptiste Daroussin break; 212c76f0793SBaptiste Daroussin case KEY_DOWN: 213f499134dSBaptiste Daroussin c[sel].value = c[sel].value > 0 ? c[sel].value - 1 : c[sel].max; 214c76f0793SBaptiste Daroussin break; 215f499134dSBaptiste Daroussin case KEY_F(1): 2168c4f4028SBaptiste Daroussin if (conf->f1_file == NULL && conf->f1_message == NULL) 217f499134dSBaptiste Daroussin break; 218f499134dSBaptiste Daroussin curs_set(0); 219f499134dSBaptiste Daroussin if (f1help(conf) != 0) 220f499134dSBaptiste Daroussin return BSDDIALOG_ERROR; 221f499134dSBaptiste Daroussin curs_set(2); 222f499134dSBaptiste Daroussin /* No break! the terminal size can change */ 223f499134dSBaptiste Daroussin case KEY_RESIZE: 224f499134dSBaptiste Daroussin hide_widget(y, x, h, w,conf->shadow); 225f499134dSBaptiste Daroussin 226f499134dSBaptiste Daroussin /* 227f499134dSBaptiste Daroussin * Unnecessary, but, when the columns decrease the 228f499134dSBaptiste Daroussin * following "refresh" seem not work 229f499134dSBaptiste Daroussin */ 230f499134dSBaptiste Daroussin refresh(); 231f499134dSBaptiste Daroussin 232f499134dSBaptiste Daroussin if (set_widget_size(conf, rows, cols, &h, &w) != 0) 233f499134dSBaptiste Daroussin return BSDDIALOG_ERROR; 234f499134dSBaptiste Daroussin if (datetime_autosize(conf, rows, cols, &h, &w, MINWTIME, text, bs) != 0) 235f499134dSBaptiste Daroussin return BSDDIALOG_ERROR; 236f499134dSBaptiste Daroussin if (datetime_checksize(h, w, text, MINWTIME, bs) != 0) 237f499134dSBaptiste Daroussin return BSDDIALOG_ERROR; 238f499134dSBaptiste Daroussin if (set_widget_position(conf, &y, &x, h, w) != 0) 239f499134dSBaptiste Daroussin return BSDDIALOG_ERROR; 240f499134dSBaptiste Daroussin 241f499134dSBaptiste Daroussin wclear(shadow); 242f499134dSBaptiste Daroussin mvwin(shadow, y + t.shadow.h, x + t.shadow.w); 243f499134dSBaptiste Daroussin wresize(shadow, h, w); 244f499134dSBaptiste Daroussin 245f499134dSBaptiste Daroussin wclear(widget); 246f499134dSBaptiste Daroussin mvwin(widget, y, x); 247f499134dSBaptiste Daroussin wresize(widget, h, w); 248f499134dSBaptiste Daroussin 249f499134dSBaptiste Daroussin htextpad = 1; 250f499134dSBaptiste Daroussin wclear(textpad); 251f499134dSBaptiste Daroussin wresize(textpad, 1, w - HBORDERS - t.text.hmargin * 2); 252f499134dSBaptiste Daroussin 253f499134dSBaptiste Daroussin if(update_widget_withtextpad(conf, shadow, widget, h, w, 254f499134dSBaptiste Daroussin RAISED, textpad, &htextpad, text, true) != 0) 255f499134dSBaptiste Daroussin return BSDDIALOG_ERROR; 256f499134dSBaptiste Daroussin 257f499134dSBaptiste Daroussin mvwaddch(widget, h - 5, w/2 - 3, ':'); 258f499134dSBaptiste Daroussin mvwaddch(widget, h - 5, w/2 + 2, ':'); 259f499134dSBaptiste Daroussin 260f499134dSBaptiste Daroussin draw_buttons(widget, h-2, w, bs, true); 261f499134dSBaptiste Daroussin 262f499134dSBaptiste Daroussin wrefresh(widget); 263f499134dSBaptiste Daroussin 264f499134dSBaptiste Daroussin prefresh(textpad, 0, 0, y+1, x+2, y+h-7, x+w-2); 265f499134dSBaptiste Daroussin 266f499134dSBaptiste Daroussin wclear(c[0].win); 267f499134dSBaptiste Daroussin mvwin(c[0].win, y + h - 6, x + w/2 - 7); 268f499134dSBaptiste Daroussin draw_borders(conf, c[0].win, 3, 4, LOWERED); 269f499134dSBaptiste Daroussin wrefresh(c[0].win); 270f499134dSBaptiste Daroussin 271f499134dSBaptiste Daroussin wclear(c[1].win); 272f499134dSBaptiste Daroussin mvwin(c[1].win, y + h - 6, x + w/2 - 2); 273f499134dSBaptiste Daroussin draw_borders(conf, c[1].win, 3, 4, LOWERED); 274f499134dSBaptiste Daroussin wrefresh(c[1].win); 275f499134dSBaptiste Daroussin 276f499134dSBaptiste Daroussin wclear(c[2].win); 277f499134dSBaptiste Daroussin mvwin(c[2].win, y + h - 6, x + w/2 + 3); 278f499134dSBaptiste Daroussin draw_borders(conf, c[2].win, 3, 4, LOWERED); 279f499134dSBaptiste Daroussin wrefresh(c[2].win); 280f499134dSBaptiste Daroussin 281f499134dSBaptiste Daroussin /* Important to avoid grey lines expanding screen */ 282f499134dSBaptiste Daroussin refresh(); 283f499134dSBaptiste Daroussin break; 284f499134dSBaptiste Daroussin default: 285f499134dSBaptiste Daroussin for (i = 0; i < (int) bs.nbuttons; i++) 286f499134dSBaptiste Daroussin if (tolower(input) == tolower((bs.label[i])[0])) { 287f499134dSBaptiste Daroussin output = bs.value[i]; 288f499134dSBaptiste Daroussin loop = false; 289f499134dSBaptiste Daroussin } 290c76f0793SBaptiste Daroussin } 291c76f0793SBaptiste Daroussin } 292c76f0793SBaptiste Daroussin 293c76f0793SBaptiste Daroussin curs_set(0); 294c76f0793SBaptiste Daroussin 295c76f0793SBaptiste Daroussin for (i=0; i<3; i++) 296c76f0793SBaptiste Daroussin delwin(c[i].win); 297f499134dSBaptiste Daroussin end_widget_withtextpad(conf, widget, h, w, textpad, shadow); 298c76f0793SBaptiste Daroussin 299c76f0793SBaptiste Daroussin return output; 300c76f0793SBaptiste Daroussin } 301c76f0793SBaptiste Daroussin 302f499134dSBaptiste Daroussin int 303f499134dSBaptiste Daroussin bsddialog_datebox(struct bsddialog_conf *conf, char* text, int rows, int cols, 304c76f0793SBaptiste Daroussin unsigned int *yy, unsigned int *mm, unsigned int *dd) 305c76f0793SBaptiste Daroussin { 306f499134dSBaptiste Daroussin WINDOW *widget, *textpad, *shadow; 307f499134dSBaptiste Daroussin int i, input, output, y, x, h, w, sel, htextpad; 308c76f0793SBaptiste Daroussin struct buttons bs; 309f499134dSBaptiste Daroussin bool loop; 310c76f0793SBaptiste Daroussin struct calendar { 311f499134dSBaptiste Daroussin int max; 312f499134dSBaptiste Daroussin int value; 313c76f0793SBaptiste Daroussin WINDOW *win; 314c76f0793SBaptiste Daroussin unsigned int x; 315f499134dSBaptiste Daroussin }; 316c76f0793SBaptiste Daroussin struct month { 317c76f0793SBaptiste Daroussin char *name; 318c76f0793SBaptiste Daroussin unsigned int days; 319c76f0793SBaptiste Daroussin }; 320c76f0793SBaptiste Daroussin 321f499134dSBaptiste Daroussin if (yy == NULL || mm == NULL || dd == NULL) 322f499134dSBaptiste Daroussin RETURN_ERROR("yy / mm / dd cannot be NULL"); 323c76f0793SBaptiste Daroussin 324f499134dSBaptiste Daroussin struct calendar c[3] = { 325f499134dSBaptiste Daroussin {9999, *yy, NULL, 4 }, 326f499134dSBaptiste Daroussin {12, *mm, NULL, 9 }, 327f499134dSBaptiste Daroussin {31, *dd, NULL, 2 } 328f499134dSBaptiste Daroussin }; 329c76f0793SBaptiste Daroussin 330f499134dSBaptiste Daroussin struct month m[12] = { 331f499134dSBaptiste Daroussin { "January", 31 }, { "February", 28 }, { "March", 31 }, 332f499134dSBaptiste Daroussin { "April", 30 }, { "May", 31 }, { "June", 30 }, 333f499134dSBaptiste Daroussin { "July", 31 }, { "August", 31 }, { "September", 30 }, 334f499134dSBaptiste Daroussin { "October", 31 }, { "November", 30 }, { "December", 31 } 335f499134dSBaptiste Daroussin }; 336f499134dSBaptiste Daroussin 337f499134dSBaptiste Daroussin #define ISLEAF(year) ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) 338f499134dSBaptiste Daroussin 339f499134dSBaptiste Daroussin for (i = 0 ; i < 3; i++) { 340f499134dSBaptiste Daroussin if (c[i].value > c[i].max) 341f499134dSBaptiste Daroussin c[i].value = c[i].max; 342f499134dSBaptiste Daroussin if (c[i].value < 1) 343f499134dSBaptiste Daroussin c[i].value = 1; 344f499134dSBaptiste Daroussin } 345f499134dSBaptiste Daroussin c[2].max = m[c[1].value -1].days; 346f499134dSBaptiste Daroussin if (c[1].value == 2 && ISLEAF(c[0].value)) 347f499134dSBaptiste Daroussin c[2].max = 29; 348f499134dSBaptiste Daroussin if (c[2].value > c[2].max) 349f499134dSBaptiste Daroussin c[2].value = c[2].max; 350c76f0793SBaptiste Daroussin 351c76f0793SBaptiste Daroussin get_buttons(conf, &bs, BUTTONLABEL(ok_label), BUTTONLABEL(extra_label), 352c76f0793SBaptiste Daroussin BUTTONLABEL(cancel_label), BUTTONLABEL(help_label)); 353c76f0793SBaptiste Daroussin 354f499134dSBaptiste Daroussin if (set_widget_size(conf, rows, cols, &h, &w) != 0) 355f499134dSBaptiste Daroussin return BSDDIALOG_ERROR; 356f499134dSBaptiste Daroussin if (datetime_autosize(conf, rows, cols, &h, &w, MINWDATE, text, bs) != 0) 357f499134dSBaptiste Daroussin return BSDDIALOG_ERROR; 358f499134dSBaptiste Daroussin if (datetime_checksize(h, w, text, MINWDATE, bs) != 0) 359f499134dSBaptiste Daroussin return BSDDIALOG_ERROR; 360f499134dSBaptiste Daroussin if (set_widget_position(conf, &y, &x, h, w) != 0) 361f499134dSBaptiste Daroussin return BSDDIALOG_ERROR; 362f499134dSBaptiste Daroussin 363f499134dSBaptiste Daroussin if (new_widget_withtextpad(conf, &shadow, &widget, y, x, h, w, RAISED, 364f499134dSBaptiste Daroussin &textpad, &htextpad, text, true) != 0) 365f499134dSBaptiste Daroussin return BSDDIALOG_ERROR; 366f499134dSBaptiste Daroussin 367f499134dSBaptiste Daroussin draw_buttons(widget, h-2, w, bs, true); 368f499134dSBaptiste Daroussin 369f499134dSBaptiste Daroussin wrefresh(widget); 370f499134dSBaptiste Daroussin 371f499134dSBaptiste Daroussin prefresh(textpad, 0, 0, y+1, x+2, y+h-7, x+w-2); 372f499134dSBaptiste Daroussin 373f499134dSBaptiste Daroussin c[0].win = new_boxed_window(conf, y + h - 6, x + w/2 - 11, 3, 6, LOWERED); 374f499134dSBaptiste Daroussin mvwaddch(widget, h - 5, w/2 - 5, '/'); 375f499134dSBaptiste Daroussin c[1].win = new_boxed_window(conf, y + h - 6, x + w/2 - 4, 3, 11, LOWERED); 376f499134dSBaptiste Daroussin mvwaddch(widget, h - 5, w/2 + 7, '/'); 377f499134dSBaptiste Daroussin c[2].win = new_boxed_window(conf, y + h - 6, x + w/2 + 8, 3, 4, LOWERED); 378f499134dSBaptiste Daroussin 379f499134dSBaptiste Daroussin wrefresh(widget); 380f499134dSBaptiste Daroussin 381c76f0793SBaptiste Daroussin sel = 2; 382c76f0793SBaptiste Daroussin curs_set(2); 383f499134dSBaptiste Daroussin loop = true; 384c76f0793SBaptiste Daroussin while(loop) { 385f499134dSBaptiste Daroussin mvwprintw(c[0].win, 1, 1, "%4d", c[0].value); 386f499134dSBaptiste Daroussin mvwprintw(c[1].win, 1, 1, "%9s", m[c[1].value-1].name); 387f499134dSBaptiste Daroussin mvwprintw(c[2].win, 1, 1, "%2d", c[2].value); 388c76f0793SBaptiste Daroussin for (i=0; i<3; i++) { 389c76f0793SBaptiste Daroussin wrefresh(c[i].win); 390c76f0793SBaptiste Daroussin } 391c76f0793SBaptiste Daroussin wmove(c[sel].win, 1, c[sel].x); 392c76f0793SBaptiste Daroussin wrefresh(c[sel].win); 393c76f0793SBaptiste Daroussin 394c76f0793SBaptiste Daroussin input = getch(); 395c76f0793SBaptiste Daroussin switch(input) { 396f499134dSBaptiste Daroussin case KEY_ENTER: 397f499134dSBaptiste Daroussin case 10: /* Enter */ 398f499134dSBaptiste Daroussin output = bs.value[bs.curr]; 3998c4f4028SBaptiste Daroussin if (output == BSDDIALOG_OK) { 400f499134dSBaptiste Daroussin *yy = c[0].value; 401f499134dSBaptiste Daroussin *mm = c[1].value; 402f499134dSBaptiste Daroussin *dd = c[2].value; 403c76f0793SBaptiste Daroussin } 404c76f0793SBaptiste Daroussin loop = false; 405c76f0793SBaptiste Daroussin break; 406f499134dSBaptiste Daroussin case 27: /* Esc */ 407c76f0793SBaptiste Daroussin output = BSDDIALOG_ESC; 408c76f0793SBaptiste Daroussin loop = false; 409c76f0793SBaptiste Daroussin break; 410f499134dSBaptiste Daroussin case '\t': /* TAB */ 411c76f0793SBaptiste Daroussin sel = (sel + 1) % 3; 412c76f0793SBaptiste Daroussin break; 413c76f0793SBaptiste Daroussin case KEY_LEFT: 414c76f0793SBaptiste Daroussin if (bs.curr > 0) { 415c76f0793SBaptiste Daroussin bs.curr--; 416f499134dSBaptiste Daroussin draw_buttons(widget, h-2, w, bs, true); 417f499134dSBaptiste Daroussin wrefresh(widget); 418c76f0793SBaptiste Daroussin } 419c76f0793SBaptiste Daroussin break; 420c76f0793SBaptiste Daroussin case KEY_RIGHT: 421c76f0793SBaptiste Daroussin if (bs.curr < (int) bs.nbuttons - 1) { 422c76f0793SBaptiste Daroussin bs.curr++; 423f499134dSBaptiste Daroussin draw_buttons(widget, h-2, w, bs, true); 424f499134dSBaptiste Daroussin wrefresh(widget); 425c76f0793SBaptiste Daroussin } 426c76f0793SBaptiste Daroussin break; 427c76f0793SBaptiste Daroussin case KEY_UP: 428f499134dSBaptiste Daroussin c[sel].value = c[sel].value > 1 ? c[sel].value - 1 : c[sel].max ; 429f499134dSBaptiste Daroussin /* if mount change */ 430f499134dSBaptiste Daroussin c[2].max = m[c[1].value -1].days; 431f499134dSBaptiste Daroussin /* if year change */ 432f499134dSBaptiste Daroussin if (c[1].value == 2 && ISLEAF(c[0].value)) 433f499134dSBaptiste Daroussin c[2].max = 29; 434f499134dSBaptiste Daroussin /* set new day */ 435f499134dSBaptiste Daroussin if (c[2].value > c[2].max) 436f499134dSBaptiste Daroussin c[2].value = c[2].max; 437c76f0793SBaptiste Daroussin break; 438c76f0793SBaptiste Daroussin case KEY_DOWN: 439f499134dSBaptiste Daroussin c[sel].value = c[sel].value < c[sel].max ? c[sel].value + 1 : 1; 440f499134dSBaptiste Daroussin /* if mount change */ 441f499134dSBaptiste Daroussin c[2].max = m[c[1].value -1].days; 442f499134dSBaptiste Daroussin /* if year change */ 443f499134dSBaptiste Daroussin if (c[1].value == 2 && ISLEAF(c[0].value)) 444f499134dSBaptiste Daroussin c[2].max = 29; 445f499134dSBaptiste Daroussin /* set new day */ 446f499134dSBaptiste Daroussin if (c[2].value > c[2].max) 447f499134dSBaptiste Daroussin c[2].value = c[2].max; 448c76f0793SBaptiste Daroussin break; 449f499134dSBaptiste Daroussin case KEY_F(1): 4508c4f4028SBaptiste Daroussin if (conf->f1_file == NULL && conf->f1_message == NULL) 451f499134dSBaptiste Daroussin break; 452f499134dSBaptiste Daroussin curs_set(0); 453f499134dSBaptiste Daroussin if (f1help(conf) != 0) 454f499134dSBaptiste Daroussin return BSDDIALOG_ERROR; 455f499134dSBaptiste Daroussin curs_set(2); 456f499134dSBaptiste Daroussin /* No break! the terminal size can change */ 457f499134dSBaptiste Daroussin case KEY_RESIZE: 458f499134dSBaptiste Daroussin hide_widget(y, x, h, w,conf->shadow); 459f499134dSBaptiste Daroussin 460f499134dSBaptiste Daroussin /* 461f499134dSBaptiste Daroussin * Unnecessary, but, when the columns decrease the 462f499134dSBaptiste Daroussin * following "refresh" seem not work 463f499134dSBaptiste Daroussin */ 464f499134dSBaptiste Daroussin refresh(); 465f499134dSBaptiste Daroussin 466f499134dSBaptiste Daroussin if (set_widget_size(conf, rows, cols, &h, &w) != 0) 467f499134dSBaptiste Daroussin return BSDDIALOG_ERROR; 468f499134dSBaptiste Daroussin if (datetime_autosize(conf, rows, cols, &h, &w, MINWDATE, text, bs) != 0) 469f499134dSBaptiste Daroussin return BSDDIALOG_ERROR; 470f499134dSBaptiste Daroussin if (datetime_checksize(h, w, text, MINWDATE, bs) != 0) 471f499134dSBaptiste Daroussin return BSDDIALOG_ERROR; 472f499134dSBaptiste Daroussin if (set_widget_position(conf, &y, &x, h, w) != 0) 473f499134dSBaptiste Daroussin return BSDDIALOG_ERROR; 474f499134dSBaptiste Daroussin 475f499134dSBaptiste Daroussin wclear(shadow); 476f499134dSBaptiste Daroussin mvwin(shadow, y + t.shadow.h, x + t.shadow.w); 477f499134dSBaptiste Daroussin wresize(shadow, h, w); 478f499134dSBaptiste Daroussin 479f499134dSBaptiste Daroussin wclear(widget); 480f499134dSBaptiste Daroussin mvwin(widget, y, x); 481f499134dSBaptiste Daroussin wresize(widget, h, w); 482f499134dSBaptiste Daroussin 483f499134dSBaptiste Daroussin htextpad = 1; 484f499134dSBaptiste Daroussin wclear(textpad); 485f499134dSBaptiste Daroussin wresize(textpad, 1, w - HBORDERS - t.text.hmargin * 2); 486f499134dSBaptiste Daroussin 487f499134dSBaptiste Daroussin if(update_widget_withtextpad(conf, shadow, widget, h, w, 488f499134dSBaptiste Daroussin RAISED, textpad, &htextpad, text, true) != 0) 489f499134dSBaptiste Daroussin return BSDDIALOG_ERROR; 490f499134dSBaptiste Daroussin 491f499134dSBaptiste Daroussin mvwaddch(widget, h - 5, w/2 - 5, '/'); 492f499134dSBaptiste Daroussin mvwaddch(widget, h - 5, w/2 + 7, '/'); 493f499134dSBaptiste Daroussin 494f499134dSBaptiste Daroussin draw_buttons(widget, h-2, w, bs, true); 495f499134dSBaptiste Daroussin 496f499134dSBaptiste Daroussin wrefresh(widget); 497f499134dSBaptiste Daroussin 498f499134dSBaptiste Daroussin prefresh(textpad, 0, 0, y+1, x+2, y+h-7, x+w-2); 499f499134dSBaptiste Daroussin 500f499134dSBaptiste Daroussin wclear(c[0].win); 501f499134dSBaptiste Daroussin mvwin(c[0].win, y + h - 6, x + w/2 - 11); 502f499134dSBaptiste Daroussin draw_borders(conf, c[0].win, 3, 6, LOWERED); 503f499134dSBaptiste Daroussin wrefresh(c[0].win); 504f499134dSBaptiste Daroussin 505f499134dSBaptiste Daroussin wclear(c[1].win); 506f499134dSBaptiste Daroussin mvwin(c[1].win, y + h - 6, x + w/2 - 4); 507f499134dSBaptiste Daroussin draw_borders(conf, c[1].win, 3, 11, LOWERED); 508f499134dSBaptiste Daroussin wrefresh(c[1].win); 509f499134dSBaptiste Daroussin 510f499134dSBaptiste Daroussin wclear(c[2].win); 511f499134dSBaptiste Daroussin mvwin(c[2].win, y + h - 6, x + w/2 + 8); 512f499134dSBaptiste Daroussin draw_borders(conf, c[2].win, 3, 4, LOWERED); 513f499134dSBaptiste Daroussin wrefresh(c[2].win); 514f499134dSBaptiste Daroussin 515f499134dSBaptiste Daroussin /* Important to avoid grey lines expanding screen */ 516f499134dSBaptiste Daroussin refresh(); 517f499134dSBaptiste Daroussin break; 518f499134dSBaptiste Daroussin default: 519f499134dSBaptiste Daroussin for (i = 0; i < (int) bs.nbuttons; i++) 520f499134dSBaptiste Daroussin if (tolower(input) == tolower((bs.label[i])[0])) { 521f499134dSBaptiste Daroussin output = bs.value[i]; 522f499134dSBaptiste Daroussin loop = false; 523f499134dSBaptiste Daroussin } 524c76f0793SBaptiste Daroussin } 525c76f0793SBaptiste Daroussin } 526c76f0793SBaptiste Daroussin 527c76f0793SBaptiste Daroussin curs_set(0); 528c76f0793SBaptiste Daroussin 529c76f0793SBaptiste Daroussin for (i=0; i<3; i++) 530c76f0793SBaptiste Daroussin delwin(c[i].win); 531f499134dSBaptiste Daroussin end_widget_withtextpad(conf, widget, h, w, textpad, shadow); 532c76f0793SBaptiste Daroussin 533c76f0793SBaptiste Daroussin return output; 534c76f0793SBaptiste Daroussin } 535