summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/calcurse.h1
-rw-r--r--src/ui-calendar.c203
-rw-r--r--src/utils.c11
3 files changed, 116 insertions, 99 deletions
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;