From ebb811605632a1bfd75c1dadd2edf26950c6966c Mon Sep 17 00:00:00 2001 From: Lukas Fleischer Date: Fri, 10 Apr 2015 09:29:17 +0200 Subject: Split out code for drawing week numbers This allows for easily adding week numbers to other panel modes, such as the monthly view. Signed-off-by: Lukas Fleischer --- src/calcurse.h | 1 + src/ui-calendar.c | 203 ++++++++++++++++++++++++++++-------------------------- src/utils.c | 11 ++- 3 files changed, 116 insertions(+), 99 deletions(-) (limited to 'src') diff --git a/src/calcurse.h b/src/calcurse.h index a1b59cf..efbdb81 100644 --- a/src/calcurse.h +++ b/src/calcurse.h @@ -1051,6 +1051,7 @@ int is_all_digit(const char *); long get_item_time(long); int get_item_hour(long); int get_item_min(long); +struct tm date2tm(struct date, unsigned, unsigned); time_t date2sec(struct date, unsigned, unsigned); time_t utcdate2sec(struct date, unsigned, unsigned); char *date_sec2date_str(long, const char *); diff --git a/src/ui-calendar.c b/src/ui-calendar.c index 2259c7f..6bc1b0f 100644 --- a/src/ui-calendar.c +++ b/src/ui-calendar.c @@ -281,6 +281,109 @@ void ui_calendar_monthly_view_cache_set_invalid(void) monthly_view_cache_valid = 0; } +static int weeknum(const struct tm *t, int firstweekday) +{ + 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; + + return wnum; +} + +/* + * Compute the week number according to ISO 8601. + */ +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; +} + +static struct tm get_first_weekday(unsigned sunday_first) +{ + int c_wday, days_to_remove; + struct tm t; + + 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; + + t = date2tm(slctd_day, 0, 0); + date_change(&t, 0, -days_to_remove); + + return t; +} + +static void draw_week_number(struct scrollwin *sw, struct tm t) +{ + int weeknum = ISO8601weeknum(&t); + + WINS_CALENDAR_LOCK; + werase(sw_cal.inner); + custom_apply_attr(sw->inner, ATTR_HIGHEST); + mvwprintw(sw->win, conf.compact_panels ? 0 : 2, sw->w - 9, + "(# %02d)", weeknum); + custom_remove_attr(sw->inner, ATTR_HIGHEST); + WINS_CALENDAR_UNLOCK; +} + /* Draw the monthly view inside calendar panel. */ static void draw_monthly_view(struct scrollwin *sw, struct date *current_day, @@ -398,79 +501,6 @@ draw_monthly_view(struct scrollwin *sw, struct date *current_day, monthly_view_cache_valid = 1; } -static int weeknum(const struct tm *t, int firstweekday) -{ - 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; - - return wnum; -} - -/* - * Compute the week number according to ISO 8601. - */ -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; -} - /* Draw the weekly view inside calendar panel. */ static void draw_weekly_view(struct scrollwin *sw, struct date *current_day, @@ -478,35 +508,14 @@ draw_weekly_view(struct scrollwin *sw, struct date *current_day, { #define DAYSLICESNO 6 const int WCALWIDTH = 28; - struct tm t; - int OFFY, OFFX, j, c_wday, days_to_remove, weeknum; + struct tm t = get_first_weekday(sunday_first); + int OFFY, OFFX, j; OFFY = 0; OFFX = (wins_sbar_width() - 2 - WCALWIDTH) / 2; - /* 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; - werase(sw_cal.inner); - custom_apply_attr(sw->inner, ATTR_HIGHEST); - mvwprintw(sw->win, conf.compact_panels ? 0 : 2, sw->w - 9, - "(# %02d)", weeknum); - custom_remove_attr(sw->inner, ATTR_HIGHEST); - WINS_CALENDAR_UNLOCK; + draw_week_number(sw, t); /* Now draw calendar view. */ for (j = 0; j < WEEKINDAYS; j++) { diff --git a/src/utils.c b/src/utils.c index f726260..415924a 100644 --- a/src/utils.c +++ b/src/utils.c @@ -363,7 +363,7 @@ int get_item_min(long date) return lt.tm_min; } -time_t date2sec(struct date day, unsigned hour, unsigned min) +struct tm date2tm(struct date day, unsigned hour, unsigned min) { time_t t = now(); struct tm start; @@ -378,7 +378,14 @@ time_t date2sec(struct date day, unsigned hour, unsigned min) start.tm_sec = 0; start.tm_isdst = -1; - t = mktime(&start); + return start; +} + +time_t date2sec(struct date day, unsigned hour, unsigned min) +{ + struct tm start = date2tm(day, hour, min); + time_t t = mktime(&start); + EXIT_IF(t == -1, _("failure in mktime")); return t; -- cgit v1.2.3-70-g09d2