From a90f680d70318f8c2751b58b15aa41d9602e1325 Mon Sep 17 00:00:00 2001 From: Frederic Culot Date: Tue, 25 Aug 2009 14:51:41 +0000 Subject: Display week number inside weekly calendar view. --- src/calendar.c | 161 +++++++++++++++++++++++++++++++++++++++++++++------------ src/calendar.h | 6 ++- 2 files changed, 131 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/src/calendar.c b/src/calendar.c index 19e7f8e..ff2c99d 100755 --- a/src/calendar.c +++ b/src/calendar.c @@ -1,4 +1,4 @@ -/* $calcurse: calendar.c,v 1.26 2009/08/24 18:59:18 culot Exp $ */ +/* $calcurse: calendar.c,v 1.27 2009/08/25 14:51:41 culot Exp $ */ /* * Calcurse - text-based organizer @@ -79,9 +79,9 @@ static unsigned calendar_view, week_begins_on_monday; static pthread_mutex_t date_thread_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_t calendar_t_date; -static void draw_monthly_view (WINDOW *, date_t *, unsigned); -static void draw_weekly_view (WINDOW *, date_t *, unsigned); -static void (*draw_calendar[CAL_VIEWS]) (WINDOW *, date_t *, unsigned) = +static void draw_monthly_view (window_t *, date_t *, unsigned); +static void draw_weekly_view (window_t *, date_t *, unsigned); +static void (*draw_calendar[CAL_VIEWS]) (window_t *, date_t *, unsigned) = {draw_monthly_view, draw_weekly_view}; /* Switch between calendar views (monthly view is selected by default). */ @@ -116,7 +116,7 @@ calendar_date_thread (void *arg) (void)sleep (tomorrow - actual); calendar_set_current_date (); - calendar_update_panel (win[CAL].p); + calendar_update_panel (&win[CAL]); } } @@ -287,7 +287,7 @@ date_change (struct tm *date, int delta_month, int delta_day) /* Draw the monthly view inside calendar panel. */ static void -draw_monthly_view (WINDOW *cwin, date_t *current_day, unsigned sunday_first) +draw_monthly_view (window_t *cwin, date_t *current_day, unsigned sunday_first) { date_t check_day; int c_day, c_day_1, day_1_sav, numdays, j; @@ -314,20 +314,20 @@ draw_monthly_view (WINDOW *cwin, date_t *current_day, unsigned sunday_first) 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 */ - custom_apply_attr (cwin, ATTR_HIGHEST); - mvwprintw (cwin, ofs_y, (CALWIDTH - (strlen (_(monthnames[mo - 1])) + 5)) / 2, + custom_apply_attr (cwin->p, ATTR_HIGHEST); + mvwprintw (cwin->p, ofs_y, (CALWIDTH - (strlen (_(monthnames[mo - 1])) + 5)) / 2, "%s %d", _(monthnames[mo - 1]), slctd_day.yyyy); - custom_remove_attr (cwin, ATTR_HIGHEST); + 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, ATTR_HIGHEST); + custom_apply_attr (cwin->p, ATTR_HIGHEST); for (j = 0; j < WEEKINDAYS; j++) { - mvwprintw (cwin, ofs_y, ofs_x + 4 * j, "%s", + mvwprintw (cwin->p, ofs_y, ofs_x + 4 * j, "%s", _(daynames[1 + j - sunday_first])); } - custom_remove_attr (cwin, ATTR_HIGHEST); + custom_remove_attr (cwin->p, ATTR_HIGHEST); day_1_sav = (c_day_1 + 1) * 3 + c_day_1 - 7; @@ -353,38 +353,115 @@ draw_monthly_view (WINDOW *cwin, date_t *current_day, unsigned sunday_first) && current_day->yyyy == slctd_day.yyyy && current_day->dd != slctd_day.dd) { - custom_apply_attr (cwin, ATTR_LOWEST); - mvwprintw (cwin, ofs_y + 1, + 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, ATTR_LOWEST); + 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, ATTR_HIGHEST); - mvwprintw (cwin, ofs_y + 1, ofs_x + day_1_sav + 4 * c_day + 1, "%2d", + 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, ATTR_HIGHEST); + custom_remove_attr (cwin->p, ATTR_HIGHEST); } else if (item_this_day) { - custom_apply_attr (cwin, ATTR_LOW); - mvwprintw (cwin, ofs_y + 1, ofs_x + day_1_sav + 4 * c_day + 1, "%2d", + 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, ATTR_LOW); + custom_remove_attr (cwin->p, ATTR_LOW); } else /* otherwise, print normal days in black */ - mvwprintw (cwin, ofs_y + 1, ofs_x + day_1_sav + 4 * c_day + 1, "%2d", + mvwprintw (cwin->p, ofs_y + 1, ofs_x + day_1_sav + 4 * c_day + 1, "%2d", c_day); } } +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 + isBissextile (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 (WINDOW *cwin, date_t *current_day, unsigned sunday_first) +draw_weekly_view (window_t *cwin, date_t *current_day, unsigned sunday_first) { - int j, c_wday, days_to_remove; + int j, c_wday, days_to_remove, weeknum; struct tm t; /* Fill in a tm structure with the first day of the selected week. */ @@ -401,16 +478,29 @@ draw_weekly_view (WINDOW *cwin, date_t *current_day, unsigned sunday_first) (void)mktime (&t); (void)date_change (&t, 0, -days_to_remove); + /* Print the week number. */ + weeknum = ISO8601weeknum (&t); + custom_apply_attr (cwin->p, ATTR_HIGHEST); + mvwprintw (cwin->p, 2, cwin->w - 9, "(# %02d)", weeknum); + custom_remove_attr (cwin->p, ATTR_HIGHEST); + /* Now draw calendar view. */ for (j = 0; j < WEEKINDAYS; j++) { - unsigned attr; + date_t date; + unsigned attr, item_this_day; /* print the day names, with regards to the first day of the week */ - custom_apply_attr (cwin, ATTR_HIGHEST); - mvwprintw (cwin, 3, 1 + 4 * j, "%s", + custom_apply_attr (cwin->p, ATTR_HIGHEST); + mvwprintw (cwin->p, 3, 1 + 4 * j, "%s", _(daynames[1 + j - sunday_first])); - custom_remove_attr (cwin, ATTR_HIGHEST); + 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 @@ -420,14 +510,16 @@ draw_weekly_view (WINDOW *cwin, date_t *current_day, unsigned sunday_first) 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; if (attr) - custom_apply_attr (cwin, attr); - mvwprintw (cwin, 4, 2 + 4 * j, "%02d", t.tm_mday); + custom_apply_attr (cwin->p, attr); + mvwprintw (cwin->p, 4, 2 + 4 * j, "%02d", t.tm_mday); if (attr) - custom_remove_attr (cwin, attr); + custom_remove_attr (cwin->p, attr); /* get next day */ (void)date_change (&t, 0, 1); @@ -436,18 +528,19 @@ draw_weekly_view (WINDOW *cwin, date_t *current_day, unsigned sunday_first) /* Function used to display the calendar panel. */ void -calendar_update_panel (WINDOW *cwin) +calendar_update_panel (window_t *cwin) { date_t current_day; unsigned sunday_first; calendar_store_current_date (¤t_day); - erase_window_part (cwin, 1, 3, CALWIDTH - 2, CALHEIGHT - 2); + erase_window_part (cwin->p, 1, 3, cwin->w - 2, cwin->h - 2); + mvwhline (cwin->p, 2, 1, ACS_HLINE, cwin->w - 2); sunday_first = calendar_week_begins_on_monday () ? 0 : 1; draw_calendar[calendar_view] (cwin, ¤t_day, sunday_first); - wnoutrefresh (cwin); + wnoutrefresh (cwin->p); } /* Set the selected day in calendar to current day. */ diff --git a/src/calendar.h b/src/calendar.h index 0269f55..5b20238 100755 --- a/src/calendar.h +++ b/src/calendar.h @@ -1,4 +1,4 @@ -/* $calcurse: calendar.h,v 1.16 2009/08/24 18:59:18 culot Exp $ */ +/* $calcurse: calendar.h,v 1.17 2009/08/25 14:51:42 culot Exp $ */ /* * Calcurse - text-based organizer @@ -55,6 +55,8 @@ #include +#include "wins.h" + #define CALHEIGHT 12 #define CALWIDTH 30 @@ -114,7 +116,7 @@ void calendar_store_current_date (date_t *); void calendar_init_slctd_day (void); date_t *calendar_get_slctd_day (void); long calendar_get_slctd_day_sec (void); -void calendar_update_panel (WINDOW *); +void calendar_update_panel (window_t *); void calendar_goto_today (void); void calendar_change_day (int); void calendar_move (move_t); -- cgit v1.2.3