1*61ba55bcSBaptiste Daroussin /*- 2*61ba55bcSBaptiste Daroussin * SPDX-License-Identifier: BSD-2-Clause 3*61ba55bcSBaptiste Daroussin * 4*61ba55bcSBaptiste Daroussin * Copyright (c) 2022-2023 Alfonso Sabato Siciliano 5*61ba55bcSBaptiste Daroussin * 6*61ba55bcSBaptiste Daroussin * Redistribution and use in source and binary forms, with or without 7*61ba55bcSBaptiste Daroussin * modification, are permitted provided that the following conditions 8*61ba55bcSBaptiste Daroussin * are met: 9*61ba55bcSBaptiste Daroussin * 1. Redistributions of source code must retain the above copyright 10*61ba55bcSBaptiste Daroussin * notice, this list of conditions and the following disclaimer. 11*61ba55bcSBaptiste Daroussin * 2. Redistributions in binary form must reproduce the above copyright 12*61ba55bcSBaptiste Daroussin * notice, this list of conditions and the following disclaimer in the 13*61ba55bcSBaptiste Daroussin * documentation and/or other materials provided with the distribution. 14*61ba55bcSBaptiste Daroussin * 15*61ba55bcSBaptiste Daroussin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16*61ba55bcSBaptiste Daroussin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17*61ba55bcSBaptiste Daroussin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18*61ba55bcSBaptiste Daroussin * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19*61ba55bcSBaptiste Daroussin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20*61ba55bcSBaptiste Daroussin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21*61ba55bcSBaptiste Daroussin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22*61ba55bcSBaptiste Daroussin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23*61ba55bcSBaptiste Daroussin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24*61ba55bcSBaptiste Daroussin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25*61ba55bcSBaptiste Daroussin * SUCH DAMAGE. 26*61ba55bcSBaptiste Daroussin */ 27*61ba55bcSBaptiste Daroussin 28*61ba55bcSBaptiste Daroussin #include <curses.h> 29*61ba55bcSBaptiste Daroussin #include <stdlib.h> 30*61ba55bcSBaptiste Daroussin #include <string.h> 31*61ba55bcSBaptiste Daroussin 32*61ba55bcSBaptiste Daroussin #include "bsddialog.h" 33*61ba55bcSBaptiste Daroussin #include "bsddialog_theme.h" 34*61ba55bcSBaptiste Daroussin #include "lib_util.h" 35*61ba55bcSBaptiste Daroussin 36*61ba55bcSBaptiste Daroussin /* Calendar */ 37*61ba55bcSBaptiste Daroussin #define MIN_YEAR_CAL 0 38*61ba55bcSBaptiste Daroussin #define MAX_YEAR_CAL 999999999 39*61ba55bcSBaptiste Daroussin #define MINHCAL 13 40*61ba55bcSBaptiste Daroussin #define MINWCAL 36 /* 34 calendar, 1 + 1 margins */ 41*61ba55bcSBaptiste Daroussin /* Datebox */ 42*61ba55bcSBaptiste Daroussin #define MIN_YEAR_DATE 0 43*61ba55bcSBaptiste Daroussin #define MAX_YEAR_DATE 9999 44*61ba55bcSBaptiste Daroussin #define MINWDATE 23 /* 3 windows and their borders */ 45*61ba55bcSBaptiste Daroussin 46*61ba55bcSBaptiste Daroussin #define ISLEAP(year) ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0) 47*61ba55bcSBaptiste Daroussin 48*61ba55bcSBaptiste Daroussin static int minyear; 49*61ba55bcSBaptiste Daroussin static int maxyear; 50*61ba55bcSBaptiste Daroussin 51*61ba55bcSBaptiste Daroussin static const char *m[12] = { 52*61ba55bcSBaptiste Daroussin "January", 53*61ba55bcSBaptiste Daroussin "February", 54*61ba55bcSBaptiste Daroussin "March", 55*61ba55bcSBaptiste Daroussin "April", 56*61ba55bcSBaptiste Daroussin "May", 57*61ba55bcSBaptiste Daroussin "June", 58*61ba55bcSBaptiste Daroussin "July", 59*61ba55bcSBaptiste Daroussin "August", 60*61ba55bcSBaptiste Daroussin "September", 61*61ba55bcSBaptiste Daroussin "October", 62*61ba55bcSBaptiste Daroussin "November", 63*61ba55bcSBaptiste Daroussin "December" 64*61ba55bcSBaptiste Daroussin }; 65*61ba55bcSBaptiste Daroussin 66*61ba55bcSBaptiste Daroussin enum operation { 67*61ba55bcSBaptiste Daroussin UP_DAY, 68*61ba55bcSBaptiste Daroussin DOWN_DAY, 69*61ba55bcSBaptiste Daroussin LEFT_DAY, 70*61ba55bcSBaptiste Daroussin RIGHT_DAY, 71*61ba55bcSBaptiste Daroussin UP_MONTH, 72*61ba55bcSBaptiste Daroussin DOWN_MONTH, 73*61ba55bcSBaptiste Daroussin UP_YEAR, 74*61ba55bcSBaptiste Daroussin DOWN_YEAR 75*61ba55bcSBaptiste Daroussin }; 76*61ba55bcSBaptiste Daroussin 77*61ba55bcSBaptiste Daroussin /* private datebox item */ 78*61ba55bcSBaptiste Daroussin struct dateitem { 79*61ba55bcSBaptiste Daroussin enum operation up; 80*61ba55bcSBaptiste Daroussin enum operation down; 81*61ba55bcSBaptiste Daroussin WINDOW *win; 82*61ba55bcSBaptiste Daroussin int width; 83*61ba55bcSBaptiste Daroussin const char *fmt; 84*61ba55bcSBaptiste Daroussin int *value; 85*61ba55bcSBaptiste Daroussin }; 86*61ba55bcSBaptiste Daroussin 87*61ba55bcSBaptiste Daroussin static int month_days(int yy, int mm) 88*61ba55bcSBaptiste Daroussin { 89*61ba55bcSBaptiste Daroussin int days; 90*61ba55bcSBaptiste Daroussin 91*61ba55bcSBaptiste Daroussin if (mm == 2) 92*61ba55bcSBaptiste Daroussin days = ISLEAP(yy) ? 29 : 28; 93*61ba55bcSBaptiste Daroussin else if (mm == 4 || mm == 6 || mm == 9 || mm == 11) 94*61ba55bcSBaptiste Daroussin days = 30; 95*61ba55bcSBaptiste Daroussin else 96*61ba55bcSBaptiste Daroussin days = 31; 97*61ba55bcSBaptiste Daroussin 98*61ba55bcSBaptiste Daroussin return (days); 99*61ba55bcSBaptiste Daroussin } 100*61ba55bcSBaptiste Daroussin 101*61ba55bcSBaptiste Daroussin static int week_day(int yy, int mm, int dd) 102*61ba55bcSBaptiste Daroussin { 103*61ba55bcSBaptiste Daroussin int wd; 104*61ba55bcSBaptiste Daroussin 105*61ba55bcSBaptiste Daroussin dd += mm < 3 ? yy-- : yy - 2; 106*61ba55bcSBaptiste Daroussin wd = 23*mm/9 + dd + 4 + yy/4 - yy/100 + yy/400; 107*61ba55bcSBaptiste Daroussin wd %= 7; 108*61ba55bcSBaptiste Daroussin 109*61ba55bcSBaptiste Daroussin return (wd); 110*61ba55bcSBaptiste Daroussin } 111*61ba55bcSBaptiste Daroussin 112*61ba55bcSBaptiste Daroussin static void 113*61ba55bcSBaptiste Daroussin init_date(unsigned int *year, unsigned int *month, unsigned int *day, int *yy, 114*61ba55bcSBaptiste Daroussin int *mm, int *dd) 115*61ba55bcSBaptiste Daroussin { 116*61ba55bcSBaptiste Daroussin *yy = MIN(*year, (unsigned int)maxyear); 117*61ba55bcSBaptiste Daroussin if (*yy < minyear) 118*61ba55bcSBaptiste Daroussin *yy = minyear; 119*61ba55bcSBaptiste Daroussin *mm = MIN(*month, 12); 120*61ba55bcSBaptiste Daroussin if (*mm == 0) 121*61ba55bcSBaptiste Daroussin *mm = 1; 122*61ba55bcSBaptiste Daroussin *dd = (*day == 0) ? 1 : *day; 123*61ba55bcSBaptiste Daroussin if(*dd > month_days(*yy, *mm)) 124*61ba55bcSBaptiste Daroussin *dd = month_days(*yy, *mm); 125*61ba55bcSBaptiste Daroussin } 126*61ba55bcSBaptiste Daroussin 127*61ba55bcSBaptiste Daroussin static void datectl(enum operation op, int *yy, int *mm, int *dd) 128*61ba55bcSBaptiste Daroussin { 129*61ba55bcSBaptiste Daroussin int ndays; 130*61ba55bcSBaptiste Daroussin 131*61ba55bcSBaptiste Daroussin ndays = month_days(*yy, *mm); 132*61ba55bcSBaptiste Daroussin 133*61ba55bcSBaptiste Daroussin switch (op) { 134*61ba55bcSBaptiste Daroussin case UP_DAY: 135*61ba55bcSBaptiste Daroussin if (*dd > 7) 136*61ba55bcSBaptiste Daroussin *dd -= 7; 137*61ba55bcSBaptiste Daroussin else { 138*61ba55bcSBaptiste Daroussin if (*mm == 1) { 139*61ba55bcSBaptiste Daroussin *yy -= 1; 140*61ba55bcSBaptiste Daroussin *mm = 12; 141*61ba55bcSBaptiste Daroussin } else 142*61ba55bcSBaptiste Daroussin *mm -= 1; 143*61ba55bcSBaptiste Daroussin ndays = month_days(*yy, *mm); 144*61ba55bcSBaptiste Daroussin *dd = ndays - abs(7 - *dd); 145*61ba55bcSBaptiste Daroussin } 146*61ba55bcSBaptiste Daroussin break; 147*61ba55bcSBaptiste Daroussin case DOWN_DAY: 148*61ba55bcSBaptiste Daroussin if (*dd + 7 < ndays) 149*61ba55bcSBaptiste Daroussin *dd += 7; 150*61ba55bcSBaptiste Daroussin else { 151*61ba55bcSBaptiste Daroussin if (*mm == 12) { 152*61ba55bcSBaptiste Daroussin *yy += 1; 153*61ba55bcSBaptiste Daroussin *mm = 1; 154*61ba55bcSBaptiste Daroussin } else 155*61ba55bcSBaptiste Daroussin *mm += 1; 156*61ba55bcSBaptiste Daroussin *dd = *dd + 7 - ndays; 157*61ba55bcSBaptiste Daroussin } 158*61ba55bcSBaptiste Daroussin break; 159*61ba55bcSBaptiste Daroussin case LEFT_DAY: 160*61ba55bcSBaptiste Daroussin if (*dd > 1) 161*61ba55bcSBaptiste Daroussin *dd -= 1; 162*61ba55bcSBaptiste Daroussin else { 163*61ba55bcSBaptiste Daroussin if (*mm == 1) { 164*61ba55bcSBaptiste Daroussin *yy -= 1; 165*61ba55bcSBaptiste Daroussin *mm = 12; 166*61ba55bcSBaptiste Daroussin } else 167*61ba55bcSBaptiste Daroussin *mm -= 1; 168*61ba55bcSBaptiste Daroussin *dd = month_days(*yy, *mm); 169*61ba55bcSBaptiste Daroussin } 170*61ba55bcSBaptiste Daroussin break; 171*61ba55bcSBaptiste Daroussin case RIGHT_DAY: 172*61ba55bcSBaptiste Daroussin if (*dd < ndays) 173*61ba55bcSBaptiste Daroussin *dd += 1; 174*61ba55bcSBaptiste Daroussin else { 175*61ba55bcSBaptiste Daroussin if (*mm == 12) { 176*61ba55bcSBaptiste Daroussin *yy += 1; 177*61ba55bcSBaptiste Daroussin *mm = 1; 178*61ba55bcSBaptiste Daroussin } else 179*61ba55bcSBaptiste Daroussin *mm += 1; 180*61ba55bcSBaptiste Daroussin *dd = 1; 181*61ba55bcSBaptiste Daroussin } 182*61ba55bcSBaptiste Daroussin break; 183*61ba55bcSBaptiste Daroussin case UP_MONTH: 184*61ba55bcSBaptiste Daroussin if (*mm == 1) { 185*61ba55bcSBaptiste Daroussin *mm = 12; 186*61ba55bcSBaptiste Daroussin *yy -= 1; 187*61ba55bcSBaptiste Daroussin } else 188*61ba55bcSBaptiste Daroussin *mm -= 1; 189*61ba55bcSBaptiste Daroussin ndays = month_days(*yy, *mm); 190*61ba55bcSBaptiste Daroussin if (*dd > ndays) 191*61ba55bcSBaptiste Daroussin *dd = ndays; 192*61ba55bcSBaptiste Daroussin break; 193*61ba55bcSBaptiste Daroussin case DOWN_MONTH: 194*61ba55bcSBaptiste Daroussin if (*mm == 12) { 195*61ba55bcSBaptiste Daroussin *mm = 1; 196*61ba55bcSBaptiste Daroussin *yy += 1; 197*61ba55bcSBaptiste Daroussin } else 198*61ba55bcSBaptiste Daroussin *mm += 1; 199*61ba55bcSBaptiste Daroussin ndays = month_days(*yy, *mm); 200*61ba55bcSBaptiste Daroussin if (*dd > ndays) 201*61ba55bcSBaptiste Daroussin *dd = ndays; 202*61ba55bcSBaptiste Daroussin break; 203*61ba55bcSBaptiste Daroussin case UP_YEAR: 204*61ba55bcSBaptiste Daroussin *yy -= 1; 205*61ba55bcSBaptiste Daroussin ndays = month_days(*yy, *mm); 206*61ba55bcSBaptiste Daroussin if (*dd > ndays) 207*61ba55bcSBaptiste Daroussin *dd = ndays; 208*61ba55bcSBaptiste Daroussin break; 209*61ba55bcSBaptiste Daroussin case DOWN_YEAR: 210*61ba55bcSBaptiste Daroussin *yy += 1; 211*61ba55bcSBaptiste Daroussin ndays = month_days(*yy, *mm); 212*61ba55bcSBaptiste Daroussin if (*dd > ndays) 213*61ba55bcSBaptiste Daroussin *dd = ndays; 214*61ba55bcSBaptiste Daroussin break; 215*61ba55bcSBaptiste Daroussin } 216*61ba55bcSBaptiste Daroussin 217*61ba55bcSBaptiste Daroussin if (*yy < minyear) { 218*61ba55bcSBaptiste Daroussin *yy = minyear; 219*61ba55bcSBaptiste Daroussin *mm = 1; 220*61ba55bcSBaptiste Daroussin *dd = 1; 221*61ba55bcSBaptiste Daroussin } 222*61ba55bcSBaptiste Daroussin if (*yy > maxyear) { 223*61ba55bcSBaptiste Daroussin *yy = maxyear; 224*61ba55bcSBaptiste Daroussin *mm = 12; 225*61ba55bcSBaptiste Daroussin *dd = 31; 226*61ba55bcSBaptiste Daroussin } 227*61ba55bcSBaptiste Daroussin } 228*61ba55bcSBaptiste Daroussin 229*61ba55bcSBaptiste Daroussin static void 230*61ba55bcSBaptiste Daroussin drawsquare(struct bsddialog_conf *conf, WINDOW *win, enum elevation elev, 231*61ba55bcSBaptiste Daroussin const char *fmt, int value, bool focus) 232*61ba55bcSBaptiste Daroussin { 233*61ba55bcSBaptiste Daroussin int h, l, w; 234*61ba55bcSBaptiste Daroussin 235*61ba55bcSBaptiste Daroussin getmaxyx(win, h, w); 236*61ba55bcSBaptiste Daroussin draw_borders(conf, win, elev); 237*61ba55bcSBaptiste Daroussin if (focus) { 238*61ba55bcSBaptiste Daroussin l = 2 + w%2; 239*61ba55bcSBaptiste Daroussin wattron(win, t.dialog.arrowcolor); 240*61ba55bcSBaptiste Daroussin mvwhline(win, 0, w/2 - l/2, 241*61ba55bcSBaptiste Daroussin conf->ascii_lines ? '^' : ACS_UARROW, l); 242*61ba55bcSBaptiste Daroussin mvwhline(win, h-1, w/2 - l/2, 243*61ba55bcSBaptiste Daroussin conf->ascii_lines ? 'v' : ACS_DARROW, l); 244*61ba55bcSBaptiste Daroussin wattroff(win, t.dialog.arrowcolor); 245*61ba55bcSBaptiste Daroussin } 246*61ba55bcSBaptiste Daroussin 247*61ba55bcSBaptiste Daroussin if (focus) 248*61ba55bcSBaptiste Daroussin wattron(win, t.menu.f_namecolor); 249*61ba55bcSBaptiste Daroussin if (strchr(fmt, 's') != NULL) 250*61ba55bcSBaptiste Daroussin mvwprintw(win, 1, 1, fmt, m[value - 1]); 251*61ba55bcSBaptiste Daroussin else 252*61ba55bcSBaptiste Daroussin mvwprintw(win, 1, 1, fmt, value); 253*61ba55bcSBaptiste Daroussin if (focus) 254*61ba55bcSBaptiste Daroussin wattroff(win, t.menu.f_namecolor); 255*61ba55bcSBaptiste Daroussin 256*61ba55bcSBaptiste Daroussin wnoutrefresh(win); 257*61ba55bcSBaptiste Daroussin } 258*61ba55bcSBaptiste Daroussin 259*61ba55bcSBaptiste Daroussin static void 260*61ba55bcSBaptiste Daroussin print_calendar(struct bsddialog_conf *conf, WINDOW *win, int yy, int mm, int dd, 261*61ba55bcSBaptiste Daroussin bool active) 262*61ba55bcSBaptiste Daroussin { 263*61ba55bcSBaptiste Daroussin int ndays, i, y, x, wd, h, w; 264*61ba55bcSBaptiste Daroussin 265*61ba55bcSBaptiste Daroussin getmaxyx(win, h, w); 266*61ba55bcSBaptiste Daroussin wclear(win); 267*61ba55bcSBaptiste Daroussin draw_borders(conf, win, RAISED); 268*61ba55bcSBaptiste Daroussin if (active) { 269*61ba55bcSBaptiste Daroussin wattron(win, t.dialog.arrowcolor); 270*61ba55bcSBaptiste Daroussin mvwhline(win, 0, 15, conf->ascii_lines ? '^' : ACS_UARROW, 4); 271*61ba55bcSBaptiste Daroussin mvwhline(win, h-1, 15, conf->ascii_lines ? 'v' : ACS_DARROW, 4); 272*61ba55bcSBaptiste Daroussin mvwvline(win, 3, 0, conf->ascii_lines ? '<' : ACS_LARROW, 3); 273*61ba55bcSBaptiste Daroussin mvwvline(win, 3, w-1, conf->ascii_lines ? '>' : ACS_RARROW, 3); 274*61ba55bcSBaptiste Daroussin wattroff(win, t.dialog.arrowcolor); 275*61ba55bcSBaptiste Daroussin } 276*61ba55bcSBaptiste Daroussin 277*61ba55bcSBaptiste Daroussin mvwaddstr(win, 1, 5, "Sun Mon Tue Wed Thu Fri Sat"); 278*61ba55bcSBaptiste Daroussin ndays = month_days(yy, mm); 279*61ba55bcSBaptiste Daroussin y = 2; 280*61ba55bcSBaptiste Daroussin wd = week_day(yy, mm, 1); 281*61ba55bcSBaptiste Daroussin for (i = 1; i <= ndays; i++) { 282*61ba55bcSBaptiste Daroussin x = 5 + (4 * wd); /* x has to be 6 with week number */ 283*61ba55bcSBaptiste Daroussin wmove(win, y, x); 284*61ba55bcSBaptiste Daroussin mvwprintw(win, y, x, "%2d", i); 285*61ba55bcSBaptiste Daroussin if (i == dd) { 286*61ba55bcSBaptiste Daroussin wattron(win, t.menu.f_namecolor); 287*61ba55bcSBaptiste Daroussin mvwprintw(win, y, x, "%2d", i); 288*61ba55bcSBaptiste Daroussin wattroff(win, t.menu.f_namecolor); 289*61ba55bcSBaptiste Daroussin } 290*61ba55bcSBaptiste Daroussin wd++; 291*61ba55bcSBaptiste Daroussin if (wd > 6) { 292*61ba55bcSBaptiste Daroussin wd = 0; 293*61ba55bcSBaptiste Daroussin y++; 294*61ba55bcSBaptiste Daroussin } 295*61ba55bcSBaptiste Daroussin } 296*61ba55bcSBaptiste Daroussin 297*61ba55bcSBaptiste Daroussin wnoutrefresh(win); 298*61ba55bcSBaptiste Daroussin } 299*61ba55bcSBaptiste Daroussin 300*61ba55bcSBaptiste Daroussin static int 301*61ba55bcSBaptiste Daroussin calendar_redraw(struct dialog *d, WINDOW *yy_win, WINDOW *mm_win, 302*61ba55bcSBaptiste Daroussin WINDOW *dd_win) 303*61ba55bcSBaptiste Daroussin { 304*61ba55bcSBaptiste Daroussin int ycal, xcal; 305*61ba55bcSBaptiste Daroussin 306*61ba55bcSBaptiste Daroussin if (d->built) { 307*61ba55bcSBaptiste Daroussin hide_dialog(d); 308*61ba55bcSBaptiste Daroussin refresh(); /* Important for decreasing screen */ 309*61ba55bcSBaptiste Daroussin } 310*61ba55bcSBaptiste Daroussin if (dialog_size_position(d, MINHCAL, MINWCAL, NULL) != 0) 311*61ba55bcSBaptiste Daroussin return (BSDDIALOG_ERROR); 312*61ba55bcSBaptiste Daroussin if (draw_dialog(d) != 0) 313*61ba55bcSBaptiste Daroussin return (BSDDIALOG_ERROR); 314*61ba55bcSBaptiste Daroussin if (d->built) 315*61ba55bcSBaptiste Daroussin refresh(); /* Important to fix grey lines expanding screen */ 316*61ba55bcSBaptiste Daroussin TEXTPAD(d, MINHCAL + HBUTTONS); 317*61ba55bcSBaptiste Daroussin 318*61ba55bcSBaptiste Daroussin ycal = d->y + d->h - 15; 319*61ba55bcSBaptiste Daroussin xcal = d->x + d->w/2 - 17; 320*61ba55bcSBaptiste Daroussin mvwaddstr(d->widget, d->h - 16, d->w/2 - 17, "Month"); 321*61ba55bcSBaptiste Daroussin update_box(d->conf, mm_win, ycal, xcal, 3, 17, RAISED); 322*61ba55bcSBaptiste Daroussin mvwaddstr(d->widget, d->h - 16, d->w/2, "Year"); 323*61ba55bcSBaptiste Daroussin update_box(d->conf, yy_win, ycal, xcal + 17, 3, 17, RAISED); 324*61ba55bcSBaptiste Daroussin update_box(d->conf, dd_win, ycal + 3, xcal, 9, 34, RAISED); 325*61ba55bcSBaptiste Daroussin wnoutrefresh(d->widget); 326*61ba55bcSBaptiste Daroussin 327*61ba55bcSBaptiste Daroussin return (0); 328*61ba55bcSBaptiste Daroussin } 329*61ba55bcSBaptiste Daroussin 330*61ba55bcSBaptiste Daroussin int 331*61ba55bcSBaptiste Daroussin bsddialog_calendar(struct bsddialog_conf *conf, const char *text, int rows, 332*61ba55bcSBaptiste Daroussin int cols, unsigned int *year, unsigned int *month, unsigned int *day) 333*61ba55bcSBaptiste Daroussin { 334*61ba55bcSBaptiste Daroussin bool loop, focusbuttons; 335*61ba55bcSBaptiste Daroussin int retval, sel, yy, mm, dd; 336*61ba55bcSBaptiste Daroussin wint_t input; 337*61ba55bcSBaptiste Daroussin WINDOW *yy_win, *mm_win, *dd_win; 338*61ba55bcSBaptiste Daroussin struct dialog d; 339*61ba55bcSBaptiste Daroussin 340*61ba55bcSBaptiste Daroussin CHECK_PTR(year); 341*61ba55bcSBaptiste Daroussin CHECK_PTR(month); 342*61ba55bcSBaptiste Daroussin CHECK_PTR(day); 343*61ba55bcSBaptiste Daroussin minyear = MIN_YEAR_CAL; 344*61ba55bcSBaptiste Daroussin maxyear = MAX_YEAR_CAL; 345*61ba55bcSBaptiste Daroussin init_date(year, month, day, &yy, &mm, &dd); 346*61ba55bcSBaptiste Daroussin 347*61ba55bcSBaptiste Daroussin if (prepare_dialog(conf, text, rows, cols, &d) != 0) 348*61ba55bcSBaptiste Daroussin return (BSDDIALOG_ERROR); 349*61ba55bcSBaptiste Daroussin set_buttons(&d, true, OK_LABEL, CANCEL_LABEL); 350*61ba55bcSBaptiste Daroussin if ((yy_win = newwin(1, 1, 1, 1)) == NULL) 351*61ba55bcSBaptiste Daroussin RETURN_ERROR("Cannot build WINDOW for yy"); 352*61ba55bcSBaptiste Daroussin wbkgd(yy_win, t.dialog.color); 353*61ba55bcSBaptiste Daroussin if ((mm_win = newwin(1, 1, 1, 1)) == NULL) 354*61ba55bcSBaptiste Daroussin RETURN_ERROR("Cannot build WINDOW for mm"); 355*61ba55bcSBaptiste Daroussin wbkgd(mm_win, t.dialog.color); 356*61ba55bcSBaptiste Daroussin if ((dd_win = newwin(1, 1, 1, 1)) == NULL) 357*61ba55bcSBaptiste Daroussin RETURN_ERROR("Cannot build WINDOW for dd"); 358*61ba55bcSBaptiste Daroussin wbkgd(dd_win, t.dialog.color); 359*61ba55bcSBaptiste Daroussin if (calendar_redraw(&d, yy_win, mm_win, dd_win) != 0) 360*61ba55bcSBaptiste Daroussin return (BSDDIALOG_ERROR); 361*61ba55bcSBaptiste Daroussin 362*61ba55bcSBaptiste Daroussin sel = -1; 363*61ba55bcSBaptiste Daroussin loop = focusbuttons = true; 364*61ba55bcSBaptiste Daroussin while (loop) { 365*61ba55bcSBaptiste Daroussin drawsquare(conf, mm_win, RAISED, "%15s", mm, sel == 0); 366*61ba55bcSBaptiste Daroussin drawsquare(conf, yy_win, RAISED, "%15d", yy, sel == 1); 367*61ba55bcSBaptiste Daroussin print_calendar(conf, dd_win, yy, mm, dd, sel == 2); 368*61ba55bcSBaptiste Daroussin doupdate(); 369*61ba55bcSBaptiste Daroussin 370*61ba55bcSBaptiste Daroussin if (get_wch(&input) == ERR) 371*61ba55bcSBaptiste Daroussin continue; 372*61ba55bcSBaptiste Daroussin switch(input) { 373*61ba55bcSBaptiste Daroussin case KEY_ENTER: 374*61ba55bcSBaptiste Daroussin case 10: /* Enter */ 375*61ba55bcSBaptiste Daroussin if (focusbuttons || conf->button.always_active) { 376*61ba55bcSBaptiste Daroussin retval = BUTTONVALUE(d.bs); 377*61ba55bcSBaptiste Daroussin loop = false; 378*61ba55bcSBaptiste Daroussin } 379*61ba55bcSBaptiste Daroussin break; 380*61ba55bcSBaptiste Daroussin case 27: /* Esc */ 381*61ba55bcSBaptiste Daroussin if (conf->key.enable_esc) { 382*61ba55bcSBaptiste Daroussin retval = BSDDIALOG_ESC; 383*61ba55bcSBaptiste Daroussin loop = false; 384*61ba55bcSBaptiste Daroussin } 385*61ba55bcSBaptiste Daroussin break; 386*61ba55bcSBaptiste Daroussin case '\t': /* TAB */ 387*61ba55bcSBaptiste Daroussin if (focusbuttons) { 388*61ba55bcSBaptiste Daroussin d.bs.curr++; 389*61ba55bcSBaptiste Daroussin if (d.bs.curr >= (int)d.bs.nbuttons) { 390*61ba55bcSBaptiste Daroussin focusbuttons = false; 391*61ba55bcSBaptiste Daroussin sel = 0; 392*61ba55bcSBaptiste Daroussin d.bs.curr = conf->button.always_active ? 393*61ba55bcSBaptiste Daroussin 0 : -1; 394*61ba55bcSBaptiste Daroussin } 395*61ba55bcSBaptiste Daroussin } else { 396*61ba55bcSBaptiste Daroussin sel++; 397*61ba55bcSBaptiste Daroussin if (sel > 2) { 398*61ba55bcSBaptiste Daroussin focusbuttons = true; 399*61ba55bcSBaptiste Daroussin sel = -1; 400*61ba55bcSBaptiste Daroussin d.bs.curr = 0; 401*61ba55bcSBaptiste Daroussin } 402*61ba55bcSBaptiste Daroussin } 403*61ba55bcSBaptiste Daroussin DRAW_BUTTONS(d); 404*61ba55bcSBaptiste Daroussin break; 405*61ba55bcSBaptiste Daroussin case KEY_RIGHT: 406*61ba55bcSBaptiste Daroussin if (focusbuttons) { 407*61ba55bcSBaptiste Daroussin d.bs.curr++; 408*61ba55bcSBaptiste Daroussin if (d.bs.curr >= (int)d.bs.nbuttons) { 409*61ba55bcSBaptiste Daroussin focusbuttons = false; 410*61ba55bcSBaptiste Daroussin sel = 0; 411*61ba55bcSBaptiste Daroussin d.bs.curr = conf->button.always_active ? 412*61ba55bcSBaptiste Daroussin 0 : -1; 413*61ba55bcSBaptiste Daroussin } 414*61ba55bcSBaptiste Daroussin } else if (sel == 2) { 415*61ba55bcSBaptiste Daroussin datectl(RIGHT_DAY, &yy, &mm, &dd); 416*61ba55bcSBaptiste Daroussin } else { /* Month or Year*/ 417*61ba55bcSBaptiste Daroussin sel++; 418*61ba55bcSBaptiste Daroussin } 419*61ba55bcSBaptiste Daroussin DRAW_BUTTONS(d); 420*61ba55bcSBaptiste Daroussin break; 421*61ba55bcSBaptiste Daroussin case KEY_LEFT: 422*61ba55bcSBaptiste Daroussin if (focusbuttons) { 423*61ba55bcSBaptiste Daroussin d.bs.curr--; 424*61ba55bcSBaptiste Daroussin if (d.bs.curr < 0) { 425*61ba55bcSBaptiste Daroussin focusbuttons = false; 426*61ba55bcSBaptiste Daroussin sel = 2; 427*61ba55bcSBaptiste Daroussin d.bs.curr = conf->button.always_active ? 428*61ba55bcSBaptiste Daroussin 0 : -1; 429*61ba55bcSBaptiste Daroussin } 430*61ba55bcSBaptiste Daroussin } else if (sel == 2) { 431*61ba55bcSBaptiste Daroussin datectl(LEFT_DAY, &yy, &mm, &dd); 432*61ba55bcSBaptiste Daroussin } else if (sel == 1) { 433*61ba55bcSBaptiste Daroussin sel = 0; 434*61ba55bcSBaptiste Daroussin } else { /* sel = 0, Month */ 435*61ba55bcSBaptiste Daroussin focusbuttons = true; 436*61ba55bcSBaptiste Daroussin sel = -1; 437*61ba55bcSBaptiste Daroussin d.bs.curr = 0; 438*61ba55bcSBaptiste Daroussin } 439*61ba55bcSBaptiste Daroussin DRAW_BUTTONS(d); 440*61ba55bcSBaptiste Daroussin break; 441*61ba55bcSBaptiste Daroussin case KEY_UP: 442*61ba55bcSBaptiste Daroussin if (focusbuttons) { 443*61ba55bcSBaptiste Daroussin sel = 2; 444*61ba55bcSBaptiste Daroussin focusbuttons = false; 445*61ba55bcSBaptiste Daroussin d.bs.curr = conf->button.always_active ? 0 : -1; 446*61ba55bcSBaptiste Daroussin DRAW_BUTTONS(d); 447*61ba55bcSBaptiste Daroussin } else if (sel == 0) { 448*61ba55bcSBaptiste Daroussin datectl(UP_MONTH, &yy, &mm, &dd); 449*61ba55bcSBaptiste Daroussin } else if (sel == 1) { 450*61ba55bcSBaptiste Daroussin datectl(UP_YEAR, &yy, &mm, &dd); 451*61ba55bcSBaptiste Daroussin } else { /* sel = 2 */ 452*61ba55bcSBaptiste Daroussin datectl(UP_DAY, &yy, &mm, &dd); 453*61ba55bcSBaptiste Daroussin } 454*61ba55bcSBaptiste Daroussin break; 455*61ba55bcSBaptiste Daroussin case KEY_DOWN: 456*61ba55bcSBaptiste Daroussin if (focusbuttons) { 457*61ba55bcSBaptiste Daroussin break; 458*61ba55bcSBaptiste Daroussin } else if (sel == 0) { 459*61ba55bcSBaptiste Daroussin datectl(DOWN_MONTH, &yy, &mm, &dd); 460*61ba55bcSBaptiste Daroussin } else if (sel == 1) { 461*61ba55bcSBaptiste Daroussin datectl(DOWN_YEAR, &yy, &mm, &dd); 462*61ba55bcSBaptiste Daroussin } else { /* sel = 2 */ 463*61ba55bcSBaptiste Daroussin datectl(DOWN_DAY, &yy, &mm, &dd); 464*61ba55bcSBaptiste Daroussin } 465*61ba55bcSBaptiste Daroussin break; 466*61ba55bcSBaptiste Daroussin case KEY_HOME: 467*61ba55bcSBaptiste Daroussin datectl(UP_MONTH, &yy, &mm, &dd); 468*61ba55bcSBaptiste Daroussin break; 469*61ba55bcSBaptiste Daroussin case KEY_END: 470*61ba55bcSBaptiste Daroussin datectl(DOWN_MONTH, &yy, &mm, &dd); 471*61ba55bcSBaptiste Daroussin break; 472*61ba55bcSBaptiste Daroussin case KEY_PPAGE: 473*61ba55bcSBaptiste Daroussin datectl(UP_YEAR, &yy, &mm, &dd); 474*61ba55bcSBaptiste Daroussin break; 475*61ba55bcSBaptiste Daroussin case KEY_NPAGE: 476*61ba55bcSBaptiste Daroussin datectl(DOWN_YEAR, &yy, &mm, &dd); 477*61ba55bcSBaptiste Daroussin break; 478*61ba55bcSBaptiste Daroussin case KEY_F(1): 479*61ba55bcSBaptiste Daroussin if (conf->key.f1_file == NULL && 480*61ba55bcSBaptiste Daroussin conf->key.f1_message == NULL) 481*61ba55bcSBaptiste Daroussin break; 482*61ba55bcSBaptiste Daroussin if (f1help_dialog(conf) != 0) 483*61ba55bcSBaptiste Daroussin return (BSDDIALOG_ERROR); 484*61ba55bcSBaptiste Daroussin if (calendar_redraw(&d, yy_win, mm_win, dd_win) != 0) 485*61ba55bcSBaptiste Daroussin return (BSDDIALOG_ERROR); 486*61ba55bcSBaptiste Daroussin break; 487*61ba55bcSBaptiste Daroussin case KEY_RESIZE: 488*61ba55bcSBaptiste Daroussin if (calendar_redraw(&d, yy_win, mm_win, dd_win) != 0) 489*61ba55bcSBaptiste Daroussin return (BSDDIALOG_ERROR); 490*61ba55bcSBaptiste Daroussin break; 491*61ba55bcSBaptiste Daroussin default: 492*61ba55bcSBaptiste Daroussin if (shortcut_buttons(input, &d.bs)) { 493*61ba55bcSBaptiste Daroussin DRAW_BUTTONS(d); 494*61ba55bcSBaptiste Daroussin doupdate(); 495*61ba55bcSBaptiste Daroussin retval = BUTTONVALUE(d.bs); 496*61ba55bcSBaptiste Daroussin loop = false; 497*61ba55bcSBaptiste Daroussin } 498*61ba55bcSBaptiste Daroussin } 499*61ba55bcSBaptiste Daroussin } 500*61ba55bcSBaptiste Daroussin 501*61ba55bcSBaptiste Daroussin *year = yy; 502*61ba55bcSBaptiste Daroussin *month = mm; 503*61ba55bcSBaptiste Daroussin *day = dd; 504*61ba55bcSBaptiste Daroussin 505*61ba55bcSBaptiste Daroussin delwin(yy_win); 506*61ba55bcSBaptiste Daroussin delwin(mm_win); 507*61ba55bcSBaptiste Daroussin delwin(dd_win); 508*61ba55bcSBaptiste Daroussin end_dialog(&d); 509*61ba55bcSBaptiste Daroussin 510*61ba55bcSBaptiste Daroussin return (retval); 511*61ba55bcSBaptiste Daroussin } 512*61ba55bcSBaptiste Daroussin 513*61ba55bcSBaptiste Daroussin static int datebox_redraw(struct dialog *d, struct dateitem *di) 514*61ba55bcSBaptiste Daroussin { 515*61ba55bcSBaptiste Daroussin int y, x; 516*61ba55bcSBaptiste Daroussin 517*61ba55bcSBaptiste Daroussin if (d->built) { 518*61ba55bcSBaptiste Daroussin hide_dialog(d); 519*61ba55bcSBaptiste Daroussin refresh(); /* Important for decreasing screen */ 520*61ba55bcSBaptiste Daroussin } 521*61ba55bcSBaptiste Daroussin if (dialog_size_position(d, 3 /*windows*/, MINWDATE, NULL) != 0) 522*61ba55bcSBaptiste Daroussin return (BSDDIALOG_ERROR); 523*61ba55bcSBaptiste Daroussin if (draw_dialog(d) != 0) 524*61ba55bcSBaptiste Daroussin return (BSDDIALOG_ERROR); 525*61ba55bcSBaptiste Daroussin if (d->built) 526*61ba55bcSBaptiste Daroussin refresh(); /* Important to fix grey lines expanding screen */ 527*61ba55bcSBaptiste Daroussin TEXTPAD(d, 3 /*windows*/ + HBUTTONS); 528*61ba55bcSBaptiste Daroussin 529*61ba55bcSBaptiste Daroussin y = d->y + d->h - 6; 530*61ba55bcSBaptiste Daroussin x = (d->x + d->w / 2) - 11; 531*61ba55bcSBaptiste Daroussin update_box(d->conf, di[0].win, y, x, 3, di[0].width, LOWERED); 532*61ba55bcSBaptiste Daroussin mvwaddch(d->widget, d->h - 5, x - d->x + di[0].width, '/'); 533*61ba55bcSBaptiste Daroussin x += di[0].width + 1; 534*61ba55bcSBaptiste Daroussin update_box(d->conf, di[1].win, y, x , 3, di[1].width, LOWERED); 535*61ba55bcSBaptiste Daroussin mvwaddch(d->widget, d->h - 5, x - d->x + di[1].width, '/'); 536*61ba55bcSBaptiste Daroussin x += di[1].width + 1; 537*61ba55bcSBaptiste Daroussin update_box(d->conf, di[2].win, y, x, 3, di[2].width, LOWERED); 538*61ba55bcSBaptiste Daroussin wnoutrefresh(d->widget); 539*61ba55bcSBaptiste Daroussin 540*61ba55bcSBaptiste Daroussin return (0); 541*61ba55bcSBaptiste Daroussin } 542*61ba55bcSBaptiste Daroussin 543*61ba55bcSBaptiste Daroussin static int 544*61ba55bcSBaptiste Daroussin build_dateitem(const char *format, int *yy, int *mm, int *dd, 545*61ba55bcSBaptiste Daroussin struct dateitem *dt) 546*61ba55bcSBaptiste Daroussin { 547*61ba55bcSBaptiste Daroussin int i; 548*61ba55bcSBaptiste Daroussin wchar_t *wformat; 549*61ba55bcSBaptiste Daroussin struct dateitem init[3] = { 550*61ba55bcSBaptiste Daroussin {UP_YEAR, DOWN_YEAR, NULL, 6, "%4d", yy}, 551*61ba55bcSBaptiste Daroussin {UP_MONTH, DOWN_MONTH, NULL, 11, "%9s", mm}, 552*61ba55bcSBaptiste Daroussin {LEFT_DAY, RIGHT_DAY, NULL, 4, "%02d", dd}, 553*61ba55bcSBaptiste Daroussin }; 554*61ba55bcSBaptiste Daroussin 555*61ba55bcSBaptiste Daroussin for (i = 0; i < 3; i++) { 556*61ba55bcSBaptiste Daroussin if ((init[i].win = newwin(1, 1, 1, 1)) == NULL) 557*61ba55bcSBaptiste Daroussin RETURN_FMTERROR("Cannot build WINDOW dateitem[%d]", i); 558*61ba55bcSBaptiste Daroussin wbkgd(init[i].win, t.dialog.color); 559*61ba55bcSBaptiste Daroussin } 560*61ba55bcSBaptiste Daroussin 561*61ba55bcSBaptiste Daroussin if ((wformat = alloc_mbstows(CHECK_STR(format))) == NULL) 562*61ba55bcSBaptiste Daroussin RETURN_ERROR("Cannot allocate conf.date.format in wchar_t*"); 563*61ba55bcSBaptiste Daroussin if (format == NULL || wcscmp(wformat, L"d/m/y") == 0) { 564*61ba55bcSBaptiste Daroussin dt[0] = init[2]; 565*61ba55bcSBaptiste Daroussin dt[1] = init[1]; 566*61ba55bcSBaptiste Daroussin dt[2] = init[0]; 567*61ba55bcSBaptiste Daroussin } else if (wcscmp(wformat, L"m/d/y") == 0) { 568*61ba55bcSBaptiste Daroussin dt[0] = init[1]; 569*61ba55bcSBaptiste Daroussin dt[1] = init[2]; 570*61ba55bcSBaptiste Daroussin dt[2] = init[0]; 571*61ba55bcSBaptiste Daroussin } else if (wcscmp(wformat, L"y/m/d") == 0) { 572*61ba55bcSBaptiste Daroussin dt[0] = init[0]; 573*61ba55bcSBaptiste Daroussin dt[1] = init[1]; 574*61ba55bcSBaptiste Daroussin dt[2] = init[2]; 575*61ba55bcSBaptiste Daroussin } else 576*61ba55bcSBaptiste Daroussin RETURN_FMTERROR("Invalid conf.date.format=\"%s\"", format); 577*61ba55bcSBaptiste Daroussin free(wformat); 578*61ba55bcSBaptiste Daroussin 579*61ba55bcSBaptiste Daroussin return (0); 580*61ba55bcSBaptiste Daroussin } 581*61ba55bcSBaptiste Daroussin 582*61ba55bcSBaptiste Daroussin int 583*61ba55bcSBaptiste Daroussin bsddialog_datebox(struct bsddialog_conf *conf, const char *text, int rows, 584*61ba55bcSBaptiste Daroussin int cols, unsigned int *year, unsigned int *month, unsigned int *day) 585*61ba55bcSBaptiste Daroussin { 586*61ba55bcSBaptiste Daroussin bool loop, focusbuttons; 587*61ba55bcSBaptiste Daroussin int retval, i, sel, yy, mm, dd; 588*61ba55bcSBaptiste Daroussin wint_t input; 589*61ba55bcSBaptiste Daroussin struct dateitem di[3]; 590*61ba55bcSBaptiste Daroussin struct dialog d; 591*61ba55bcSBaptiste Daroussin 592*61ba55bcSBaptiste Daroussin CHECK_PTR(year); 593*61ba55bcSBaptiste Daroussin CHECK_PTR(month); 594*61ba55bcSBaptiste Daroussin CHECK_PTR(day); 595*61ba55bcSBaptiste Daroussin minyear = MIN_YEAR_DATE; 596*61ba55bcSBaptiste Daroussin maxyear = MAX_YEAR_DATE; 597*61ba55bcSBaptiste Daroussin init_date(year, month, day, &yy, &mm, &dd); 598*61ba55bcSBaptiste Daroussin 599*61ba55bcSBaptiste Daroussin if (prepare_dialog(conf, text, rows, cols, &d) != 0) 600*61ba55bcSBaptiste Daroussin return (BSDDIALOG_ERROR); 601*61ba55bcSBaptiste Daroussin set_buttons(&d, true, OK_LABEL, CANCEL_LABEL); 602*61ba55bcSBaptiste Daroussin if (build_dateitem(conf->date.format, &yy, &mm, &dd, di) != 0) 603*61ba55bcSBaptiste Daroussin return (BSDDIALOG_ERROR); 604*61ba55bcSBaptiste Daroussin if (datebox_redraw(&d, di) != 0) 605*61ba55bcSBaptiste Daroussin return (BSDDIALOG_ERROR); 606*61ba55bcSBaptiste Daroussin 607*61ba55bcSBaptiste Daroussin sel = -1; 608*61ba55bcSBaptiste Daroussin loop = focusbuttons = true; 609*61ba55bcSBaptiste Daroussin while (loop) { 610*61ba55bcSBaptiste Daroussin for (i = 0; i < 3; i++) 611*61ba55bcSBaptiste Daroussin drawsquare(conf, di[i].win, LOWERED, di[i].fmt, 612*61ba55bcSBaptiste Daroussin *di[i].value, sel == i); 613*61ba55bcSBaptiste Daroussin doupdate(); 614*61ba55bcSBaptiste Daroussin 615*61ba55bcSBaptiste Daroussin if (get_wch(&input) == ERR) 616*61ba55bcSBaptiste Daroussin continue; 617*61ba55bcSBaptiste Daroussin switch(input) { 618*61ba55bcSBaptiste Daroussin case KEY_ENTER: 619*61ba55bcSBaptiste Daroussin case 10: /* Enter */ 620*61ba55bcSBaptiste Daroussin if (focusbuttons || conf->button.always_active) { 621*61ba55bcSBaptiste Daroussin retval = BUTTONVALUE(d.bs); 622*61ba55bcSBaptiste Daroussin loop = false; 623*61ba55bcSBaptiste Daroussin } 624*61ba55bcSBaptiste Daroussin break; 625*61ba55bcSBaptiste Daroussin case 27: /* Esc */ 626*61ba55bcSBaptiste Daroussin if (conf->key.enable_esc) { 627*61ba55bcSBaptiste Daroussin retval = BSDDIALOG_ESC; 628*61ba55bcSBaptiste Daroussin loop = false; 629*61ba55bcSBaptiste Daroussin } 630*61ba55bcSBaptiste Daroussin break; 631*61ba55bcSBaptiste Daroussin case KEY_RIGHT: 632*61ba55bcSBaptiste Daroussin case '\t': /* TAB */ 633*61ba55bcSBaptiste Daroussin if (focusbuttons) { 634*61ba55bcSBaptiste Daroussin d.bs.curr++; 635*61ba55bcSBaptiste Daroussin focusbuttons = d.bs.curr < (int)d.bs.nbuttons ? 636*61ba55bcSBaptiste Daroussin true : false; 637*61ba55bcSBaptiste Daroussin if (focusbuttons == false) { 638*61ba55bcSBaptiste Daroussin sel = 0; 639*61ba55bcSBaptiste Daroussin d.bs.curr = conf->button.always_active ? 640*61ba55bcSBaptiste Daroussin 0 : -1; 641*61ba55bcSBaptiste Daroussin } 642*61ba55bcSBaptiste Daroussin } else { 643*61ba55bcSBaptiste Daroussin sel++; 644*61ba55bcSBaptiste Daroussin focusbuttons = sel > 2 ? true : false; 645*61ba55bcSBaptiste Daroussin if (focusbuttons) { 646*61ba55bcSBaptiste Daroussin d.bs.curr = 0; 647*61ba55bcSBaptiste Daroussin } 648*61ba55bcSBaptiste Daroussin } 649*61ba55bcSBaptiste Daroussin DRAW_BUTTONS(d); 650*61ba55bcSBaptiste Daroussin break; 651*61ba55bcSBaptiste Daroussin case KEY_LEFT: 652*61ba55bcSBaptiste Daroussin if (focusbuttons) { 653*61ba55bcSBaptiste Daroussin d.bs.curr--; 654*61ba55bcSBaptiste Daroussin focusbuttons = d.bs.curr < 0 ? false : true; 655*61ba55bcSBaptiste Daroussin if (focusbuttons == false) { 656*61ba55bcSBaptiste Daroussin sel = 2; 657*61ba55bcSBaptiste Daroussin d.bs.curr = conf->button.always_active ? 658*61ba55bcSBaptiste Daroussin 0 : -1; 659*61ba55bcSBaptiste Daroussin } 660*61ba55bcSBaptiste Daroussin } else { 661*61ba55bcSBaptiste Daroussin sel--; 662*61ba55bcSBaptiste Daroussin focusbuttons = sel < 0 ? true : false; 663*61ba55bcSBaptiste Daroussin if (focusbuttons) 664*61ba55bcSBaptiste Daroussin d.bs.curr = (int)d.bs.nbuttons - 1; 665*61ba55bcSBaptiste Daroussin } 666*61ba55bcSBaptiste Daroussin DRAW_BUTTONS(d); 667*61ba55bcSBaptiste Daroussin break; 668*61ba55bcSBaptiste Daroussin case KEY_UP: 669*61ba55bcSBaptiste Daroussin if (focusbuttons) { 670*61ba55bcSBaptiste Daroussin sel = 0; 671*61ba55bcSBaptiste Daroussin focusbuttons = false; 672*61ba55bcSBaptiste Daroussin d.bs.curr = conf->button.always_active ? 0 : -1; 673*61ba55bcSBaptiste Daroussin DRAW_BUTTONS(d); 674*61ba55bcSBaptiste Daroussin } else { 675*61ba55bcSBaptiste Daroussin datectl(di[sel].up, &yy, &mm, &dd); 676*61ba55bcSBaptiste Daroussin } 677*61ba55bcSBaptiste Daroussin break; 678*61ba55bcSBaptiste Daroussin case KEY_DOWN: 679*61ba55bcSBaptiste Daroussin if (focusbuttons) 680*61ba55bcSBaptiste Daroussin break; 681*61ba55bcSBaptiste Daroussin datectl(di[sel].down, &yy, &mm, &dd); 682*61ba55bcSBaptiste Daroussin break; 683*61ba55bcSBaptiste Daroussin case KEY_F(1): 684*61ba55bcSBaptiste Daroussin if (conf->key.f1_file == NULL && 685*61ba55bcSBaptiste Daroussin conf->key.f1_message == NULL) 686*61ba55bcSBaptiste Daroussin break; 687*61ba55bcSBaptiste Daroussin if (f1help_dialog(conf) != 0) 688*61ba55bcSBaptiste Daroussin return (BSDDIALOG_ERROR); 689*61ba55bcSBaptiste Daroussin if (datebox_redraw(&d, di) != 0) 690*61ba55bcSBaptiste Daroussin return (BSDDIALOG_ERROR); 691*61ba55bcSBaptiste Daroussin break; 692*61ba55bcSBaptiste Daroussin case KEY_RESIZE: 693*61ba55bcSBaptiste Daroussin if (datebox_redraw(&d, di) != 0) 694*61ba55bcSBaptiste Daroussin return (BSDDIALOG_ERROR); 695*61ba55bcSBaptiste Daroussin break; 696*61ba55bcSBaptiste Daroussin default: 697*61ba55bcSBaptiste Daroussin if (shortcut_buttons(input, &d.bs)) { 698*61ba55bcSBaptiste Daroussin DRAW_BUTTONS(d); 699*61ba55bcSBaptiste Daroussin doupdate(); 700*61ba55bcSBaptiste Daroussin retval = BUTTONVALUE(d.bs); 701*61ba55bcSBaptiste Daroussin loop = false; 702*61ba55bcSBaptiste Daroussin } 703*61ba55bcSBaptiste Daroussin } 704*61ba55bcSBaptiste Daroussin } 705*61ba55bcSBaptiste Daroussin 706*61ba55bcSBaptiste Daroussin *year = yy; 707*61ba55bcSBaptiste Daroussin *month = mm; 708*61ba55bcSBaptiste Daroussin *day = dd; 709*61ba55bcSBaptiste Daroussin 710*61ba55bcSBaptiste Daroussin for (i = 0; i < 3 ; i++) 711*61ba55bcSBaptiste Daroussin delwin(di[i].win); 712*61ba55bcSBaptiste Daroussin end_dialog(&d); 713*61ba55bcSBaptiste Daroussin 714*61ba55bcSBaptiste Daroussin return (retval); 715*61ba55bcSBaptiste Daroussin }