diff options
Diffstat (limited to 'src/ui-calendar.c')
-rw-r--r-- | src/ui-calendar.c | 1182 |
1 files changed, 609 insertions, 573 deletions
diff --git a/src/ui-calendar.c b/src/ui-calendar.c index a312a99..f23d578 100644 --- a/src/ui-calendar.c +++ b/src/ui-calendar.c @@ -48,22 +48,22 @@ #endif #define EPOCH 90 -#define EPSILONg 279.403303 /* solar ecliptic long at EPOCH */ -#define RHOg 282.768422 /* solar ecliptic long of perigee at EPOCH */ -#define ECCEN 0.016713 /* solar orbit eccentricity */ -#define lzero 318.351648 /* lunar mean long at EPOCH */ -#define Pzero 36.340410 /* lunar mean long of perigee at EPOCH */ -#define Nzero 318.510107 /* lunar mean long of node at EPOCH */ +#define EPSILONg 279.403303 /* solar ecliptic long at EPOCH */ +#define RHOg 282.768422 /* solar ecliptic long of perigee at EPOCH */ +#define ECCEN 0.016713 /* solar orbit eccentricity */ +#define lzero 318.351648 /* lunar mean long at EPOCH */ +#define Pzero 36.340410 /* lunar mean long of perigee at EPOCH */ +#define Nzero 318.510107 /* lunar mean long of node at EPOCH */ #define ISLEAP(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0) enum pom { - NO_POM, - FIRST_QUARTER, - FULL_MOON, - LAST_QUARTER, - NEW_MOON, - MOON_PHASES + NO_POM, + FIRST_QUARTER, + FULL_MOON, + LAST_QUARTER, + NEW_MOON, + MOON_PHASES }; static struct date today, slctd_day; @@ -74,7 +74,7 @@ static pthread_t ui_calendar_t_date; static void draw_monthly_view(struct window *, struct date *, unsigned); static void draw_weekly_view(struct window *, struct date *, unsigned); static void (*draw_calendar[CAL_VIEWS]) (struct window *, struct date *, - unsigned) = { + unsigned) = { draw_monthly_view, draw_weekly_view}; static int monthly_view_cache[MAXDAYSPERMONTH]; @@ -84,168 +84,170 @@ static int monthly_view_cache_month = 0; /* Switch between calendar views (monthly view is selected by default). */ void ui_calendar_view_next(void) { - ui_calendar_view++; - if (ui_calendar_view == CAL_VIEWS) - ui_calendar_view = 0; + ui_calendar_view++; + if (ui_calendar_view == CAL_VIEWS) + ui_calendar_view = 0; } void ui_calendar_view_prev(void) { - if (ui_calendar_view == 0) - ui_calendar_view = CAL_VIEWS; - ui_calendar_view--; + if (ui_calendar_view == 0) + ui_calendar_view = CAL_VIEWS; + ui_calendar_view--; } void ui_calendar_set_view(int view) { - ui_calendar_view = (view < 0 || view >= CAL_VIEWS) ? CAL_MONTH_VIEW : view; + ui_calendar_view = (view < 0 + || view >= CAL_VIEWS) ? CAL_MONTH_VIEW : view; } int ui_calendar_get_view(void) { - return (int)ui_calendar_view; + return (int)ui_calendar_view; } /* Thread needed to update current date in calendar. */ /* ARGSUSED0 */ static void *ui_calendar_date_thread(void *arg) { - time_t actual, tomorrow; + time_t actual, tomorrow; - for (;;) { - tomorrow = (time_t) (get_today() + DAYINSEC); + for (;;) { + tomorrow = (time_t) (get_today() + DAYINSEC); - while ((actual = time(NULL)) < tomorrow) - sleep(tomorrow - actual); + while ((actual = time(NULL)) < tomorrow) + sleep(tomorrow - actual); - ui_calendar_set_current_date(); - ui_calendar_update_panel(&win[CAL]); - } + ui_calendar_set_current_date(); + ui_calendar_update_panel(&win[CAL]); + } - return NULL; + return NULL; } /* Launch the calendar date thread. */ void ui_calendar_start_date_thread(void) { - pthread_create(&ui_calendar_t_date, NULL, ui_calendar_date_thread, NULL); + pthread_create(&ui_calendar_t_date, NULL, ui_calendar_date_thread, + NULL); } /* Stop the calendar date thread. */ void ui_calendar_stop_date_thread(void) { - if (ui_calendar_t_date) { - pthread_cancel(ui_calendar_t_date); - pthread_join(ui_calendar_t_date, NULL); - } + if (ui_calendar_t_date) { + pthread_cancel(ui_calendar_t_date); + pthread_join(ui_calendar_t_date, NULL); + } } /* Set static variable today to current date */ void ui_calendar_set_current_date(void) { - time_t timer; - struct tm tm; + time_t timer; + struct tm tm; - timer = time(NULL); - localtime_r(&timer, &tm); + timer = time(NULL); + localtime_r(&timer, &tm); - pthread_mutex_lock(&date_thread_mutex); - today.dd = tm.tm_mday; - today.mm = tm.tm_mon + 1; - today.yyyy = tm.tm_year + 1900; - pthread_mutex_unlock(&date_thread_mutex); + pthread_mutex_lock(&date_thread_mutex); + today.dd = tm.tm_mday; + today.mm = tm.tm_mon + 1; + today.yyyy = tm.tm_year + 1900; + pthread_mutex_unlock(&date_thread_mutex); } /* Needed to display sunday or monday as the first day of week in calendar. */ void ui_calendar_set_first_day_of_week(enum wday first_day) { - switch (first_day) { - case SUNDAY: - week_begins_on_monday = 0; - break; - case MONDAY: - week_begins_on_monday = 1; - break; - default: - ERROR_MSG(_("ERROR setting first day of week")); - week_begins_on_monday = 0; - /* NOTREACHED */ - } + switch (first_day) { + case SUNDAY: + week_begins_on_monday = 0; + break; + case MONDAY: + week_begins_on_monday = 1; + break; + default: + ERROR_MSG(_("ERROR setting first day of week")); + week_begins_on_monday = 0; + /* NOTREACHED */ + } } /* Swap first day of week in calendar. */ void ui_calendar_change_first_day_of_week(void) { - week_begins_on_monday = !week_begins_on_monday; + week_begins_on_monday = !week_begins_on_monday; } /* Return 1 if week begins on monday, 0 otherwise. */ unsigned ui_calendar_week_begins_on_monday(void) { - return week_begins_on_monday; + return week_begins_on_monday; } /* Fill in the given variable with the current date. */ void ui_calendar_store_current_date(struct date *date) { - pthread_mutex_lock(&date_thread_mutex); - *date = today; - pthread_mutex_unlock(&date_thread_mutex); + pthread_mutex_lock(&date_thread_mutex); + *date = today; + pthread_mutex_unlock(&date_thread_mutex); } /* This is to start at the current date in calendar. */ void ui_calendar_init_slctd_day(void) { - ui_calendar_store_current_date(&slctd_day); + ui_calendar_store_current_date(&slctd_day); } /* Return the selected day in calendar */ struct date *ui_calendar_get_slctd_day(void) { - return &slctd_day; + return &slctd_day; } /* Returned value represents the selected day in calendar (in seconds) */ long ui_calendar_get_slctd_day_sec(void) { - return date2sec(slctd_day, 0, 0); + return date2sec(slctd_day, 0, 0); } static int ui_calendar_get_wday(struct date *date) { - struct tm t; + struct tm t; - memset(&t, 0, sizeof(struct tm)); - t.tm_mday = date->dd; - t.tm_mon = date->mm - 1; - t.tm_year = date->yyyy - 1900; + memset(&t, 0, sizeof(struct tm)); + t.tm_mday = date->dd; + t.tm_mon = date->mm - 1; + t.tm_year = date->yyyy - 1900; - mktime(&t); + mktime(&t); - return t.tm_wday; + return t.tm_wday; } static unsigned months_to_days(unsigned month) { - return (month * 3057 - 3007) / 100; + return (month * 3057 - 3007) / 100; } static long years_to_days(unsigned year) { - return year * 365L + year / 4 - year / 100 + year / 400; + return year * 365L + year / 4 - year / 100 + year / 400; } static long ymd_to_scalar(unsigned year, unsigned month, unsigned day) { - long scalar; + long scalar; - scalar = day + months_to_days(month); - if (month > 2) - scalar -= ISLEAP(year) ? 1 : 2; - year--; - scalar += years_to_days(year); + scalar = day + months_to_days(month); + if (month > 2) + scalar -= ISLEAP(year) ? 1 : 2; + year--; + scalar += years_to_days(year); - return scalar; + return scalar; } /* @@ -254,149 +256,156 @@ static long ymd_to_scalar(unsigned year, unsigned month, unsigned day) */ static int date_change(struct tm *date, int delta_month, int delta_day) { - struct tm t; + struct tm t; - t = *date; - t.tm_mon += delta_month; - t.tm_mday += delta_day; + t = *date; + t.tm_mon += delta_month; + t.tm_mday += delta_day; - if (mktime(&t) == -1) { - return 1; - } else { - *date = t; - return 0; - } + if (mktime(&t) == -1) { + return 1; + } else { + *date = t; + return 0; + } } void ui_calendar_monthly_view_cache_set_invalid(void) { - monthly_view_cache_valid = 0; + monthly_view_cache_valid = 0; } /* Draw the monthly view inside calendar panel. */ static void draw_monthly_view(struct window *cwin, struct date *current_day, - unsigned sunday_first) -{ - const int OFFY = CALHEIGHT / 2 - (conf.compact_panels ? 3 : 1); - struct date check_day; - int c_day, c_day_1, day_1_sav, numdays, j; - unsigned yr, mo; - int OFFX, SBAR_WIDTH, ofs_x, ofs_y; - int item_this_day = 0; - - mo = slctd_day.mm; - yr = slctd_day.yyyy; - - /* offset for centering calendar in window */ - SBAR_WIDTH = wins_sbar_width(); - OFFX = (SBAR_WIDTH - 27) / 2; - ofs_y = OFFY; - ofs_x = OFFX; - - /* checking the number of days in february */ - numdays = days[mo - 1]; - if (2 == mo && ISLEAP(yr)) - ++numdays; - - /* - * the first calendar day will be monday or sunday, depending on - * 'week_begins_on_monday' value - */ - c_day_1 = (int)((ymd_to_scalar(yr, mo, 1 + sunday_first) - (long)1) % 7L); - - /* Write the current month and year on top of the calendar */ - WINS_CALENDAR_LOCK; - custom_apply_attr(cwin->p, ATTR_HIGHEST); - mvwprintw(cwin->p, ofs_y, - (SBAR_WIDTH - (strlen(_(monthnames[mo - 1])) + 5)) / 2, - "%s %d", _(monthnames[mo - 1]), slctd_day.yyyy); - custom_remove_attr(cwin->p, ATTR_HIGHEST); - ++ofs_y; - - /* print the days, with regards to the first day of the week */ - custom_apply_attr(cwin->p, ATTR_HIGHEST); - for (j = 0; j < WEEKINDAYS; j++) { - mvwaddstr(cwin->p, ofs_y, ofs_x + 4 * j, _(daynames[1 + j - sunday_first])); - } - custom_remove_attr(cwin->p, ATTR_HIGHEST); - WINS_CALENDAR_UNLOCK; - - day_1_sav = (c_day_1 + 1) * 3 + c_day_1 - 7; - - /* invalidate cache if a new month is selected */ - if (yr * YEARINMONTHS + mo != monthly_view_cache_month) { - monthly_view_cache_month = yr * YEARINMONTHS + mo; - monthly_view_cache_valid = 0; - } - - for (c_day = 1; c_day <= numdays; ++c_day, ++c_day_1, c_day_1 %= 7) { - check_day.dd = c_day; - check_day.mm = slctd_day.mm; - check_day.yyyy = slctd_day.yyyy; - - /* check if the day contains an event or an appointment */ - if (monthly_view_cache_valid) { - item_this_day = monthly_view_cache[c_day - 1]; - } else { - item_this_day = monthly_view_cache[c_day - 1] = - day_check_if_item(check_day); - } - - /* Go to next line, the week is over. */ - if (!c_day_1 && 1 != c_day) { - ofs_y++; - ofs_x = OFFX - day_1_sav - 4 * c_day; - } - - WINS_CALENDAR_LOCK; - if (c_day == current_day->dd - && current_day->mm == slctd_day.mm - && current_day->yyyy == slctd_day.yyyy - && current_day->dd != slctd_day.dd) { - /* This is today, so print it in yellow. */ - custom_apply_attr(cwin->p, ATTR_LOWEST); - mvwprintw(cwin->p, ofs_y + 1, - ofs_x + day_1_sav + 4 * c_day + 1, "%2d", c_day); - custom_remove_attr(cwin->p, ATTR_LOWEST); - } else if (c_day == slctd_day.dd) { - /* This is the selected day, print it according to user's theme. */ - custom_apply_attr(cwin->p, ATTR_HIGHEST); - mvwprintw(cwin->p, ofs_y + 1, - ofs_x + day_1_sav + 4 * c_day + 1, "%2d", c_day); - custom_remove_attr(cwin->p, ATTR_HIGHEST); - } else if (item_this_day) { - custom_apply_attr(cwin->p, ATTR_LOW); - mvwprintw(cwin->p, ofs_y + 1, - ofs_x + day_1_sav + 4 * c_day + 1, "%2d", c_day); - custom_remove_attr(cwin->p, ATTR_LOW); - } else { - /* otherwise, print normal days in black */ - mvwprintw(cwin->p, ofs_y + 1, - ofs_x + day_1_sav + 4 * c_day + 1, "%2d", c_day); - } - WINS_CALENDAR_UNLOCK; - } - - monthly_view_cache_valid = 1; + unsigned sunday_first) +{ + const int OFFY = CALHEIGHT / 2 - (conf.compact_panels ? 3 : 1); + struct date check_day; + int c_day, c_day_1, day_1_sav, numdays, j; + unsigned yr, mo; + int OFFX, SBAR_WIDTH, ofs_x, ofs_y; + int item_this_day = 0; + + mo = slctd_day.mm; + yr = slctd_day.yyyy; + + /* offset for centering calendar in window */ + SBAR_WIDTH = wins_sbar_width(); + OFFX = (SBAR_WIDTH - 27) / 2; + ofs_y = OFFY; + ofs_x = OFFX; + + /* checking the number of days in february */ + numdays = days[mo - 1]; + if (2 == mo && ISLEAP(yr)) + ++numdays; + + /* + * the first calendar day will be monday or sunday, depending on + * 'week_begins_on_monday' value + */ + c_day_1 = + (int)((ymd_to_scalar(yr, mo, 1 + sunday_first) - + (long)1) % 7L); + + /* Write the current month and year on top of the calendar */ + WINS_CALENDAR_LOCK; + custom_apply_attr(cwin->p, ATTR_HIGHEST); + mvwprintw(cwin->p, ofs_y, + (SBAR_WIDTH - (strlen(_(monthnames[mo - 1])) + 5)) / 2, + "%s %d", _(monthnames[mo - 1]), slctd_day.yyyy); + custom_remove_attr(cwin->p, ATTR_HIGHEST); + ++ofs_y; + + /* print the days, with regards to the first day of the week */ + custom_apply_attr(cwin->p, ATTR_HIGHEST); + for (j = 0; j < WEEKINDAYS; j++) { + mvwaddstr(cwin->p, ofs_y, ofs_x + 4 * j, + _(daynames[1 + j - sunday_first])); + } + custom_remove_attr(cwin->p, ATTR_HIGHEST); + WINS_CALENDAR_UNLOCK; + + day_1_sav = (c_day_1 + 1) * 3 + c_day_1 - 7; + + /* invalidate cache if a new month is selected */ + if (yr * YEARINMONTHS + mo != monthly_view_cache_month) { + monthly_view_cache_month = yr * YEARINMONTHS + mo; + monthly_view_cache_valid = 0; + } + + for (c_day = 1; c_day <= numdays; ++c_day, ++c_day_1, c_day_1 %= 7) { + check_day.dd = c_day; + check_day.mm = slctd_day.mm; + check_day.yyyy = slctd_day.yyyy; + + /* check if the day contains an event or an appointment */ + if (monthly_view_cache_valid) { + item_this_day = monthly_view_cache[c_day - 1]; + } else { + item_this_day = monthly_view_cache[c_day - 1] = + day_check_if_item(check_day); + } + + /* Go to next line, the week is over. */ + if (!c_day_1 && 1 != c_day) { + ofs_y++; + ofs_x = OFFX - day_1_sav - 4 * c_day; + } + + WINS_CALENDAR_LOCK; + if (c_day == current_day->dd + && current_day->mm == slctd_day.mm + && current_day->yyyy == slctd_day.yyyy + && current_day->dd != slctd_day.dd) { + /* This is today, so print it in yellow. */ + custom_apply_attr(cwin->p, ATTR_LOWEST); + mvwprintw(cwin->p, ofs_y + 1, + ofs_x + day_1_sav + 4 * c_day + 1, "%2d", + c_day); + custom_remove_attr(cwin->p, ATTR_LOWEST); + } else if (c_day == slctd_day.dd) { + /* This is the selected day, print it according to user's theme. */ + custom_apply_attr(cwin->p, ATTR_HIGHEST); + mvwprintw(cwin->p, ofs_y + 1, + ofs_x + day_1_sav + 4 * c_day + 1, "%2d", + c_day); + custom_remove_attr(cwin->p, ATTR_HIGHEST); + } else if (item_this_day) { + custom_apply_attr(cwin->p, ATTR_LOW); + mvwprintw(cwin->p, ofs_y + 1, + ofs_x + day_1_sav + 4 * c_day + 1, "%2d", + c_day); + custom_remove_attr(cwin->p, ATTR_LOW); + } else { + /* otherwise, print normal days in black */ + mvwprintw(cwin->p, ofs_y + 1, + ofs_x + day_1_sav + 4 * c_day + 1, "%2d", + c_day); + } + WINS_CALENDAR_UNLOCK; + } + + monthly_view_cache_valid = 1; } static int weeknum(const struct tm *t, int firstweekday) { - int wday, wnum; + int wday, wnum; - wday = t->tm_wday; - if (firstweekday == MONDAY) { - if (wday == SUNDAY) - wday = 6; - else - wday--; - } - wnum = ((t->tm_yday + WEEKINDAYS - wday) / WEEKINDAYS); - if (wnum < 0) - wnum = 0; + wday = t->tm_wday; + if (firstweekday == MONDAY) { + if (wday == SUNDAY) + wday = 6; + else + wday--; + } + wnum = ((t->tm_yday + WEEKINDAYS - wday) / WEEKINDAYS); + if (wnum < 0) + wnum = 0; - return wnum; + return wnum; } /* @@ -404,167 +413,180 @@ static int weeknum(const struct tm *t, int firstweekday) */ static int ISO8601weeknum(const struct tm *t) { - int wnum, jan1day; - - wnum = weeknum(t, MONDAY); - - jan1day = t->tm_wday - (t->tm_yday % WEEKINDAYS); - if (jan1day < 0) - jan1day += WEEKINDAYS; - - switch (jan1day) { - case MONDAY: - break; - case TUESDAY: - case WEDNESDAY: - case THURSDAY: - wnum++; - break; - case FRIDAY: - case SATURDAY: - case SUNDAY: - if (wnum == 0) { - /* Get week number of last week of last year. */ - struct tm dec31ly; /* 12/31 last year */ - - dec31ly = *t; - dec31ly.tm_year--; - dec31ly.tm_mon = 11; - dec31ly.tm_mday = 31; - dec31ly.tm_wday = (jan1day == SUNDAY) ? 6 : jan1day - 1; - dec31ly.tm_yday = 364 + ISLEAP(dec31ly.tm_year + 1900); - wnum = ISO8601weeknum(&dec31ly); - } - break; - } - - if (t->tm_mon == 11) { - int wday, mday; - - wday = t->tm_wday; - mday = t->tm_mday; - if ((wday == MONDAY && (mday >= 29 && mday <= 31)) - || (wday == TUESDAY && (mday == 30 || mday == 31)) - || (wday == WEDNESDAY && mday == 31)) - wnum = 1; - } - - return wnum; + int wnum, jan1day; + + wnum = weeknum(t, MONDAY); + + jan1day = t->tm_wday - (t->tm_yday % WEEKINDAYS); + if (jan1day < 0) + jan1day += WEEKINDAYS; + + switch (jan1day) { + case MONDAY: + break; + case TUESDAY: + case WEDNESDAY: + case THURSDAY: + wnum++; + break; + case FRIDAY: + case SATURDAY: + case SUNDAY: + if (wnum == 0) { + /* Get week number of last week of last year. */ + struct tm dec31ly; /* 12/31 last year */ + + dec31ly = *t; + dec31ly.tm_year--; + dec31ly.tm_mon = 11; + dec31ly.tm_mday = 31; + dec31ly.tm_wday = + (jan1day == SUNDAY) ? 6 : jan1day - 1; + dec31ly.tm_yday = + 364 + ISLEAP(dec31ly.tm_year + 1900); + wnum = ISO8601weeknum(&dec31ly); + } + break; + } + + if (t->tm_mon == 11) { + int wday, mday; + + wday = t->tm_wday; + mday = t->tm_mday; + if ((wday == MONDAY && (mday >= 29 && mday <= 31)) + || (wday == TUESDAY && (mday == 30 || mday == 31)) + || (wday == WEDNESDAY && mday == 31)) + wnum = 1; + } + + return wnum; } /* Draw the weekly view inside calendar panel. */ static void draw_weekly_view(struct window *cwin, struct date *current_day, - unsigned sunday_first) + unsigned sunday_first) { #define DAYSLICESNO 6 - const int WCALWIDTH = 30; - const int OFFY = CALHEIGHT / 2 - (conf.compact_panels ? 3 : 1); - struct tm t; - int OFFX, j, c_wday, days_to_remove, weeknum; - - OFFX = (wins_sbar_width() - WCALWIDTH) / 2 + 1; - - /* Fill in a tm structure with the first day of the selected week. */ - c_wday = ui_calendar_get_wday(&slctd_day); - if (sunday_first) - days_to_remove = c_wday; - else - days_to_remove = c_wday == 0 ? WEEKINDAYS - 1 : c_wday - 1; - - memset(&t, 0, sizeof(struct tm)); - t.tm_mday = slctd_day.dd; - t.tm_mon = slctd_day.mm - 1; - t.tm_year = slctd_day.yyyy - 1900; - mktime(&t); - date_change(&t, 0, -days_to_remove); - - /* Print the week number. */ - weeknum = ISO8601weeknum(&t); - WINS_CALENDAR_LOCK; - custom_apply_attr(cwin->p, ATTR_HIGHEST); - mvwprintw(cwin->p, conf.compact_panels ? 0 : 2, cwin->w - 9, "(# %02d)", - weeknum); - custom_remove_attr(cwin->p, ATTR_HIGHEST); - WINS_CALENDAR_UNLOCK; - - /* Now draw calendar view. */ - for (j = 0; j < WEEKINDAYS; j++) { - struct date date; - unsigned attr, item_this_day; - int i, slices[DAYSLICESNO]; - - /* print the day names, with regards to the first day of the week */ - custom_apply_attr(cwin->p, ATTR_HIGHEST); - mvwaddstr(cwin->p, OFFY, OFFX + 4 * j, _(daynames[1 + j - sunday_first])); - custom_remove_attr(cwin->p, ATTR_HIGHEST); - - /* Check if the day to be printed has an item or not. */ - date.dd = t.tm_mday; - date.mm = t.tm_mon + 1; - date.yyyy = t.tm_year + 1900; - item_this_day = day_check_if_item(date); - - /* Print the day numbers with appropriate decoration. */ - if (t.tm_mday == current_day->dd - && current_day->mm == slctd_day.mm - && current_day->yyyy == slctd_day.yyyy - && current_day->dd != slctd_day.dd) - attr = ATTR_LOWEST; /* today, but not selected */ - else if (t.tm_mday == slctd_day.dd) - attr = ATTR_HIGHEST; /* selected day */ - else if (item_this_day) - attr = ATTR_LOW; - else - attr = 0; - - WINS_CALENDAR_LOCK; - if (attr) - custom_apply_attr(cwin->p, attr); - mvwprintw(cwin->p, OFFY + 1, OFFX + 1 + 4 * j, "%02d", t.tm_mday); - if (attr) - custom_remove_attr(cwin->p, attr); - WINS_CALENDAR_UNLOCK; - - /* Draw slices indicating appointment times. */ - memset(slices, 0, DAYSLICESNO * sizeof *slices); - if (day_chk_busy_slices(date, DAYSLICESNO, slices)) { - for (i = 0; i < DAYSLICESNO; i++) { - if (j != WEEKINDAYS - 1 && i != DAYSLICESNO - 1) { - WINS_CALENDAR_LOCK; - mvwhline(cwin->p, OFFY + 2 + i, OFFX + 3 + 4 * j, ACS_S9, 2); - WINS_CALENDAR_UNLOCK; - } - if (slices[i]) { - int highlight; - - highlight = (t.tm_mday == slctd_day.dd) ? 1 : 0; - WINS_CALENDAR_LOCK; - if (highlight) - custom_apply_attr(cwin->p, attr); - wattron(cwin->p, A_REVERSE); - mvwaddstr(cwin->p, OFFY + 2 + i, OFFX + 1 + 4 * j, " "); - mvwaddstr(cwin->p, OFFY + 2 + i, OFFX + 2 + 4 * j, " "); - wattroff(cwin->p, A_REVERSE); - if (highlight) - custom_remove_attr(cwin->p, attr); - WINS_CALENDAR_UNLOCK; - } - } - } - - /* get next day */ - date_change(&t, 0, 1); - } - - /* Draw marks to indicate midday on the sides of the calendar. */ - WINS_CALENDAR_LOCK; - custom_apply_attr(cwin->p, ATTR_HIGHEST); - mvwhline(cwin->p, OFFY + 1 + DAYSLICESNO / 2, OFFX, ACS_S9, 1); - mvwhline(cwin->p, OFFY + 1 + DAYSLICESNO / 2, - OFFX + WCALWIDTH - 3, ACS_S9, 1); - custom_remove_attr(cwin->p, ATTR_HIGHEST); - WINS_CALENDAR_UNLOCK; + const int WCALWIDTH = 30; + const int OFFY = CALHEIGHT / 2 - (conf.compact_panels ? 3 : 1); + struct tm t; + int OFFX, j, c_wday, days_to_remove, weeknum; + + OFFX = (wins_sbar_width() - WCALWIDTH) / 2 + 1; + + /* Fill in a tm structure with the first day of the selected week. */ + c_wday = ui_calendar_get_wday(&slctd_day); + if (sunday_first) + days_to_remove = c_wday; + else + days_to_remove = c_wday == 0 ? WEEKINDAYS - 1 : c_wday - 1; + + memset(&t, 0, sizeof(struct tm)); + t.tm_mday = slctd_day.dd; + t.tm_mon = slctd_day.mm - 1; + t.tm_year = slctd_day.yyyy - 1900; + mktime(&t); + date_change(&t, 0, -days_to_remove); + + /* Print the week number. */ + weeknum = ISO8601weeknum(&t); + WINS_CALENDAR_LOCK; + custom_apply_attr(cwin->p, ATTR_HIGHEST); + mvwprintw(cwin->p, conf.compact_panels ? 0 : 2, cwin->w - 9, + "(# %02d)", weeknum); + custom_remove_attr(cwin->p, ATTR_HIGHEST); + WINS_CALENDAR_UNLOCK; + + /* Now draw calendar view. */ + for (j = 0; j < WEEKINDAYS; j++) { + struct date date; + unsigned attr, item_this_day; + int i, slices[DAYSLICESNO]; + + /* print the day names, with regards to the first day of the week */ + custom_apply_attr(cwin->p, ATTR_HIGHEST); + mvwaddstr(cwin->p, OFFY, OFFX + 4 * j, + _(daynames[1 + j - sunday_first])); + custom_remove_attr(cwin->p, ATTR_HIGHEST); + + /* Check if the day to be printed has an item or not. */ + date.dd = t.tm_mday; + date.mm = t.tm_mon + 1; + date.yyyy = t.tm_year + 1900; + item_this_day = day_check_if_item(date); + + /* Print the day numbers with appropriate decoration. */ + if (t.tm_mday == current_day->dd + && current_day->mm == slctd_day.mm + && current_day->yyyy == slctd_day.yyyy + && current_day->dd != slctd_day.dd) + attr = ATTR_LOWEST; /* today, but not selected */ + else if (t.tm_mday == slctd_day.dd) + attr = ATTR_HIGHEST; /* selected day */ + else if (item_this_day) + attr = ATTR_LOW; + else + attr = 0; + + WINS_CALENDAR_LOCK; + if (attr) + custom_apply_attr(cwin->p, attr); + mvwprintw(cwin->p, OFFY + 1, OFFX + 1 + 4 * j, "%02d", + t.tm_mday); + if (attr) + custom_remove_attr(cwin->p, attr); + WINS_CALENDAR_UNLOCK; + + /* Draw slices indicating appointment times. */ + memset(slices, 0, DAYSLICESNO * sizeof *slices); + if (day_chk_busy_slices(date, DAYSLICESNO, slices)) { + for (i = 0; i < DAYSLICESNO; i++) { + if (j != WEEKINDAYS - 1 + && i != DAYSLICESNO - 1) { + WINS_CALENDAR_LOCK; + mvwhline(cwin->p, OFFY + 2 + i, + OFFX + 3 + 4 * j, ACS_S9, + 2); + WINS_CALENDAR_UNLOCK; + } + if (slices[i]) { + int highlight; + + highlight = + (t.tm_mday == + slctd_day.dd) ? 1 : 0; + WINS_CALENDAR_LOCK; + if (highlight) + custom_apply_attr(cwin->p, + attr); + wattron(cwin->p, A_REVERSE); + mvwaddstr(cwin->p, OFFY + 2 + i, + OFFX + 1 + 4 * j, " "); + mvwaddstr(cwin->p, OFFY + 2 + i, + OFFX + 2 + 4 * j, " "); + wattroff(cwin->p, A_REVERSE); + if (highlight) + custom_remove_attr(cwin->p, + attr); + WINS_CALENDAR_UNLOCK; + } + } + } + + /* get next day */ + date_change(&t, 0, 1); + } + + /* Draw marks to indicate midday on the sides of the calendar. */ + WINS_CALENDAR_LOCK; + custom_apply_attr(cwin->p, ATTR_HIGHEST); + mvwhline(cwin->p, OFFY + 1 + DAYSLICESNO / 2, OFFX, ACS_S9, 1); + mvwhline(cwin->p, OFFY + 1 + DAYSLICESNO / 2, + OFFX + WCALWIDTH - 3, ACS_S9, 1); + custom_remove_attr(cwin->p, ATTR_HIGHEST); + WINS_CALENDAR_UNLOCK; #undef DAYSLICESNO } @@ -572,34 +594,34 @@ draw_weekly_view(struct window *cwin, struct date *current_day, /* Function used to display the calendar panel. */ void ui_calendar_update_panel(struct window *cwin) { - struct date current_day; - unsigned sunday_first; + struct date current_day; + unsigned sunday_first; - ui_calendar_store_current_date(¤t_day); + ui_calendar_store_current_date(¤t_day); - WINS_CALENDAR_LOCK; - erase_window_part(cwin->p, 1, conf.compact_panels ? 1 : 3, cwin->w - 2, - cwin->h - 2); - if (!conf.compact_panels) - mvwhline(cwin->p, 2, 1, ACS_HLINE, cwin->w - 2); - WINS_CALENDAR_UNLOCK; + WINS_CALENDAR_LOCK; + erase_window_part(cwin->p, 1, conf.compact_panels ? 1 : 3, + cwin->w - 2, cwin->h - 2); + if (!conf.compact_panels) + mvwhline(cwin->p, 2, 1, ACS_HLINE, cwin->w - 2); + WINS_CALENDAR_UNLOCK; - sunday_first = ui_calendar_week_begins_on_monday()? 0 : 1; + sunday_first = ui_calendar_week_begins_on_monday()? 0 : 1; - draw_calendar[ui_calendar_view] (cwin, ¤t_day, sunday_first); + draw_calendar[ui_calendar_view] (cwin, ¤t_day, sunday_first); - wnoutrefresh(cwin->p); + wnoutrefresh(cwin->p); } /* Set the selected day in calendar to current day. */ void ui_calendar_goto_today(void) { - struct date today; + struct date today; - ui_calendar_store_current_date(&today); - slctd_day.dd = today.dd; - slctd_day.mm = today.mm; - slctd_day.yyyy = today.yyyy; + ui_calendar_store_current_date(&today); + slctd_day.dd = today.dd; + slctd_day.mm = today.mm; + slctd_day.yyyy = today.yyyy; } /* @@ -611,154 +633,165 @@ void ui_calendar_goto_today(void) void ui_calendar_change_day(int datefmt) { #define LDAY 11 - char selected_day[LDAY] = ""; - char outstr[BUFSIZ]; - int dday, dmonth, dyear; - int wrong_day = 1; - const char *mesg_line1 = - _("The day you entered is not valid " - "(should be between 01/01/1902 and 12/31/2037)"); - const char *mesg_line2 = _("Press [ENTER] to continue"); - const char *request_date = _("Enter the day to go to [ENTER for today] : %s"); - - while (wrong_day) { - snprintf(outstr, BUFSIZ, request_date, DATEFMT_DESC(datefmt)); - status_mesg(outstr, ""); - if (getstring(win[STA].p, selected_day, LDAY, 0, 1) == GETSTRING_ESC) { - return; - } else { - if (strlen(selected_day) == 0) { - wrong_day = 0; - ui_calendar_goto_today(); - } else if (parse_date(selected_day, datefmt, &dyear, &dmonth, &dday, - ui_calendar_get_slctd_day())) { - wrong_day = 0; - /* go to chosen day */ - slctd_day.dd = dday; - slctd_day.mm = dmonth; - slctd_day.yyyy = dyear; - } - if (wrong_day) { - status_mesg(mesg_line1, mesg_line2); - wgetch(win[KEY].p); - } - } - } - - return; + char selected_day[LDAY] = ""; + char outstr[BUFSIZ]; + int dday, dmonth, dyear; + int wrong_day = 1; + const char *mesg_line1 = + _("The day you entered is not valid " + "(should be between 01/01/1902 and 12/31/2037)"); + const char *mesg_line2 = _("Press [ENTER] to continue"); + const char *request_date = + _("Enter the day to go to [ENTER for today] : %s"); + + while (wrong_day) { + snprintf(outstr, BUFSIZ, request_date, + DATEFMT_DESC(datefmt)); + status_mesg(outstr, ""); + if (getstring(win[STA].p, selected_day, LDAY, 0, 1) == + GETSTRING_ESC) { + return; + } else { + if (strlen(selected_day) == 0) { + wrong_day = 0; + ui_calendar_goto_today(); + } else + if (parse_date + (selected_day, datefmt, &dyear, &dmonth, + &dday, ui_calendar_get_slctd_day())) { + wrong_day = 0; + /* go to chosen day */ + slctd_day.dd = dday; + slctd_day.mm = dmonth; + slctd_day.yyyy = dyear; + } + if (wrong_day) { + status_mesg(mesg_line1, mesg_line2); + wgetch(win[KEY].p); + } + } + } + + return; } void ui_calendar_move(enum move move, int count) { - int ret, days_to_remove, days_to_add; - struct tm t; - - memset(&t, 0, sizeof(struct tm)); - t.tm_mday = slctd_day.dd; - t.tm_mon = slctd_day.mm - 1; - t.tm_year = slctd_day.yyyy - 1900; - - switch (move) { - case DAY_PREV: - ret = date_change(&t, 0, -count); - break; - case DAY_NEXT: - ret = date_change(&t, 0, count); - break; - case WEEK_PREV: - ret = date_change(&t, 0, -count * WEEKINDAYS); - break; - case WEEK_NEXT: - ret = date_change(&t, 0, count * WEEKINDAYS); - break; - case MONTH_PREV: - ret = date_change(&t, -count, 0); - break; - case MONTH_NEXT: - ret = date_change(&t, count, 0); - break; - case YEAR_PREV: - ret = date_change(&t, -count * YEARINMONTHS, 0); - break; - case YEAR_NEXT: - ret = date_change(&t, count * YEARINMONTHS, 0); - break; - case WEEK_START: - /* Normalize struct tm to get week day number. */ - mktime(&t); - if (ui_calendar_week_begins_on_monday()) - days_to_remove = ((t.tm_wday == 0) ? WEEKINDAYS - 1 : t.tm_wday - 1); - else - days_to_remove = ((t.tm_wday == 0) ? 0 : t.tm_wday); - days_to_remove += (count - 1) * WEEKINDAYS; - ret = date_change(&t, 0, -days_to_remove); - break; - case WEEK_END: - mktime(&t); - if (ui_calendar_week_begins_on_monday()) - days_to_add = ((t.tm_wday == 0) ? 0 : WEEKINDAYS - t.tm_wday); - else - days_to_add = ((t.tm_wday == 0) ? - WEEKINDAYS - 1 : WEEKINDAYS - 1 - t.tm_wday); - days_to_add += (count - 1) * WEEKINDAYS; - ret = date_change(&t, 0, days_to_add); - break; - default: - ret = 1; - /* NOTREACHED */ - } - - if (ret == 0) { - if (t.tm_year < 2) { - t.tm_mday = 1; - t.tm_mon = 0; - t.tm_year = 2; - } else if (t.tm_year > 137) { - t.tm_mday = 31; - t.tm_mon = 11; - t.tm_year = 137; - } - - slctd_day.dd = t.tm_mday; - slctd_day.mm = t.tm_mon + 1; - slctd_day.yyyy = t.tm_year + 1900; - } + int ret, days_to_remove, days_to_add; + struct tm t; + + memset(&t, 0, sizeof(struct tm)); + t.tm_mday = slctd_day.dd; + t.tm_mon = slctd_day.mm - 1; + t.tm_year = slctd_day.yyyy - 1900; + + switch (move) { + case DAY_PREV: + ret = date_change(&t, 0, -count); + break; + case DAY_NEXT: + ret = date_change(&t, 0, count); + break; + case WEEK_PREV: + ret = date_change(&t, 0, -count * WEEKINDAYS); + break; + case WEEK_NEXT: + ret = date_change(&t, 0, count * WEEKINDAYS); + break; + case MONTH_PREV: + ret = date_change(&t, -count, 0); + break; + case MONTH_NEXT: + ret = date_change(&t, count, 0); + break; + case YEAR_PREV: + ret = date_change(&t, -count * YEARINMONTHS, 0); + break; + case YEAR_NEXT: + ret = date_change(&t, count * YEARINMONTHS, 0); + break; + case WEEK_START: + /* Normalize struct tm to get week day number. */ + mktime(&t); + if (ui_calendar_week_begins_on_monday()) + days_to_remove = + ((t.tm_wday == + 0) ? WEEKINDAYS - 1 : t.tm_wday - 1); + else + days_to_remove = + ((t.tm_wday == 0) ? 0 : t.tm_wday); + days_to_remove += (count - 1) * WEEKINDAYS; + ret = date_change(&t, 0, -days_to_remove); + break; + case WEEK_END: + mktime(&t); + if (ui_calendar_week_begins_on_monday()) + days_to_add = + ((t.tm_wday == + 0) ? 0 : WEEKINDAYS - t.tm_wday); + else + days_to_add = ((t.tm_wday == 0) ? + WEEKINDAYS - 1 : WEEKINDAYS - 1 - + t.tm_wday); + days_to_add += (count - 1) * WEEKINDAYS; + ret = date_change(&t, 0, days_to_add); + break; + default: + ret = 1; + /* NOTREACHED */ + } + + if (ret == 0) { + if (t.tm_year < 2) { + t.tm_mday = 1; + t.tm_mon = 0; + t.tm_year = 2; + } else if (t.tm_year > 137) { + t.tm_mday = 31; + t.tm_mon = 11; + t.tm_year = 137; + } + + slctd_day.dd = t.tm_mday; + slctd_day.mm = t.tm_mon + 1; + slctd_day.yyyy = t.tm_year + 1900; + } } /* Returns the beginning of current year as a long. */ long ui_calendar_start_of_year(void) { - time_t timer; - struct tm tm; + time_t timer; + struct tm tm; - timer = time(NULL); - localtime_r(&timer, &tm); - tm.tm_mon = 0; - tm.tm_mday = 1; - tm.tm_hour = 0; - tm.tm_min = 0; - tm.tm_sec = 0; - timer = mktime(&tm); + timer = time(NULL); + localtime_r(&timer, &tm); + tm.tm_mon = 0; + tm.tm_mday = 1; + tm.tm_hour = 0; + tm.tm_min = 0; + tm.tm_sec = 0; + timer = mktime(&tm); - return (long)timer; + return (long)timer; } long ui_calendar_end_of_year(void) { - time_t timer; - struct tm tm; + time_t timer; + struct tm tm; - timer = time(NULL); - localtime_r(&timer, &tm); - tm.tm_mon = 0; - tm.tm_mday = 1; - tm.tm_hour = 0; - tm.tm_min = 0; - tm.tm_sec = 0; - tm.tm_year++; - timer = mktime(&tm); + timer = time(NULL); + localtime_r(&timer, &tm); + tm.tm_mon = 0; + tm.tm_mday = 1; + tm.tm_hour = 0; + tm.tm_min = 0; + tm.tm_sec = 0; + tm.tm_year++; + timer = mktime(&tm); - return (long)(timer - 1); + return (long)(timer - 1); } /* @@ -804,7 +837,7 @@ long ui_calendar_end_of_year(void) */ static double dtor(double deg) { - return deg * M_PI / 180; + return deg * M_PI / 180; } /* @@ -813,13 +846,13 @@ static double dtor(double deg) */ static void adj360(double *deg) { - for (;;) - if (*deg < 0.0) - *deg += 360.0; - else if (*deg > 360.0) - *deg -= 360.0; - else - break; + for (;;) + if (*deg < 0.0) + *deg += 360.0; + else if (*deg > 360.0) + *deg -= 360.0; + else + break; } /* @@ -828,33 +861,33 @@ static void adj360(double *deg) */ static double potm(double days) { - double N, Msol, Ec, LambdaSol, l, Mm, Ev, Ac, A3, Mmprime; - double A4, lprime, V, ldprime, D, Nm; - - N = 360.0 * days / 365.242191; /* sec 46 #3 */ - adj360(&N); - Msol = N + EPSILONg - RHOg; /* sec 46 #4 */ - adj360(&Msol); - Ec = 360 / M_PI * ECCEN * sin(dtor(Msol)); /* sec 46 #5 */ - LambdaSol = N + Ec + EPSILONg; /* sec 46 #6 */ - adj360(&LambdaSol); - l = 13.1763966 * days + lzero; /* sec 65 #4 */ - adj360(&l); - Mm = l - (0.1114041 * days) - Pzero; /* sec 65 #5 */ - adj360(&Mm); - Nm = Nzero - (0.0529539 * days); /* sec 65 #6 */ - adj360(&Nm); - Ev = 1.2739 * sin(dtor(2 * (l - LambdaSol) - Mm)); /* sec 65 #7 */ - Ac = 0.1858 * sin(dtor(Msol)); /* sec 65 #8 */ - A3 = 0.37 * sin(dtor(Msol)); - Mmprime = Mm + Ev - Ac - A3; /* sec 65 #9 */ - Ec = 6.2886 * sin(dtor(Mmprime)); /* sec 65 #10 */ - A4 = 0.214 * sin(dtor(2 * Mmprime)); /* sec 65 #11 */ - lprime = l + Ev + Ec - Ac + A4; /* sec 65 #12 */ - V = 0.6583 * sin(dtor(2 * (lprime - LambdaSol))); /* sec 65 #13 */ - ldprime = lprime + V; /* sec 65 #14 */ - D = ldprime - LambdaSol; /* sec 67 #2 */ - return 50.0 * (1 - cos(dtor(D))); /* sec 67 #3 */ + double N, Msol, Ec, LambdaSol, l, Mm, Ev, Ac, A3, Mmprime; + double A4, lprime, V, ldprime, D, Nm; + + N = 360.0 * days / 365.242191; /* sec 46 #3 */ + adj360(&N); + Msol = N + EPSILONg - RHOg; /* sec 46 #4 */ + adj360(&Msol); + Ec = 360 / M_PI * ECCEN * sin(dtor(Msol)); /* sec 46 #5 */ + LambdaSol = N + Ec + EPSILONg; /* sec 46 #6 */ + adj360(&LambdaSol); + l = 13.1763966 * days + lzero; /* sec 65 #4 */ + adj360(&l); + Mm = l - (0.1114041 * days) - Pzero; /* sec 65 #5 */ + adj360(&Mm); + Nm = Nzero - (0.0529539 * days); /* sec 65 #6 */ + adj360(&Nm); + Ev = 1.2739 * sin(dtor(2 * (l - LambdaSol) - Mm)); /* sec 65 #7 */ + Ac = 0.1858 * sin(dtor(Msol)); /* sec 65 #8 */ + A3 = 0.37 * sin(dtor(Msol)); + Mmprime = Mm + Ev - Ac - A3; /* sec 65 #9 */ + Ec = 6.2886 * sin(dtor(Mmprime)); /* sec 65 #10 */ + A4 = 0.214 * sin(dtor(2 * Mmprime)); /* sec 65 #11 */ + lprime = l + Ev + Ec - Ac + A4; /* sec 65 #12 */ + V = 0.6583 * sin(dtor(2 * (lprime - LambdaSol))); /* sec 65 #13 */ + ldprime = lprime + V; /* sec 65 #14 */ + D = ldprime - LambdaSol; /* sec 67 #2 */ + return 50.0 * (1 - cos(dtor(D))); /* sec 67 #3 */ } /* @@ -870,20 +903,20 @@ static double potm(double days) */ static double pom(time_t tmpt) { - struct tm *GMT; - double days; - int cnt; + struct tm *GMT; + double days; + int cnt; - GMT = gmtime(&tmpt); - days = (GMT->tm_yday + 1) + ((GMT->tm_hour + (GMT->tm_min / 60.0) + - (GMT->tm_sec / 3600.0)) / 24.0); - for (cnt = EPOCH; cnt < GMT->tm_year; ++cnt) - days += ISLEAP(cnt + TM_YEAR_BASE) ? 366 : 365; - /* Selected time could be before EPOCH */ - for (cnt = GMT->tm_year; cnt < EPOCH; ++cnt) - days -= ISLEAP(cnt + TM_YEAR_BASE) ? 366 : 365; + GMT = gmtime(&tmpt); + days = (GMT->tm_yday + 1) + ((GMT->tm_hour + (GMT->tm_min / 60.0) + + (GMT->tm_sec / 3600.0)) / 24.0); + for (cnt = EPOCH; cnt < GMT->tm_year; ++cnt) + days += ISLEAP(cnt + TM_YEAR_BASE) ? 366 : 365; + /* Selected time could be before EPOCH */ + for (cnt = GMT->tm_year; cnt < EPOCH; ++cnt) + days -= ISLEAP(cnt + TM_YEAR_BASE) ? 366 : 365; - return potm(days); + return potm(days); } /* @@ -893,22 +926,25 @@ static double pom(time_t tmpt) */ const char *ui_calendar_get_pom(time_t date) { - const char *pom_pict[MOON_PHASES] = { " ", "|) ", "(|)", "(| ", " | " }; - enum pom phase = NO_POM; - double pom_today, relative_pom, pom_yesterday, pom_tomorrow; - const double half = 50.0; - - pom_yesterday = pom(date); - pom_today = pom(date + DAYINSEC); - relative_pom = abs(pom_today - half); - pom_tomorrow = pom(date + 2 * DAYINSEC); - if (pom_today > pom_yesterday && pom_today > pom_tomorrow) - phase = FULL_MOON; - else if (pom_today < pom_yesterday && pom_today < pom_tomorrow) - phase = NEW_MOON; - else if (relative_pom < abs(pom_yesterday - half) - && relative_pom < abs(pom_tomorrow - half)) - phase = (pom_tomorrow > pom_today) ? FIRST_QUARTER : LAST_QUARTER; - - return pom_pict[phase]; + const char *pom_pict[MOON_PHASES] = + { " ", "|) ", "(|)", "(| ", " | " }; + enum pom phase = NO_POM; + double pom_today, relative_pom, pom_yesterday, pom_tomorrow; + const double half = 50.0; + + pom_yesterday = pom(date); + pom_today = pom(date + DAYINSEC); + relative_pom = abs(pom_today - half); + pom_tomorrow = pom(date + 2 * DAYINSEC); + if (pom_today > pom_yesterday && pom_today > pom_tomorrow) + phase = FULL_MOON; + else if (pom_today < pom_yesterday && pom_today < pom_tomorrow) + phase = NEW_MOON; + else if (relative_pom < abs(pom_yesterday - half) + && relative_pom < abs(pom_tomorrow - half)) + phase = + (pom_tomorrow > + pom_today) ? FIRST_QUARTER : LAST_QUARTER; + + return pom_pict[phase]; } |