aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMorgan Seltzer <MorganSeltzer000@gmail.com>2021-06-07 17:13:23 -0400
committerLukas Fleischer <lfleischer@calcurse.org>2021-08-07 13:42:10 -0400
commite3fc73e0c76addc0893ad3ceeba7ef8442133a51 (patch)
tree16f5fe4e89f5ace43471754c170c936bc9103f4c
parent61ed5f835cae29ce6405ec34a7e310d5ea90327b (diff)
downloadcalcurse-e3fc73e0c76addc0893ad3ceeba7ef8442133a51.tar.gz
calcurse-e3fc73e0c76addc0893ad3ceeba7ef8442133a51.zip
Backend changes for first day of week
Previously only Sunday and Monday were allowed for the first day of the week, and was internally treated as a binary variable. This patch changes the backend so all days are accepted, a future patch will allow users to actually select other days. Addresses GitHub feature request #321. Signed-off-by: Morgan Seltzer <MorganSeltzer000@gmail.com> Signed-off-by: Lukas Fleischer <lfleischer@calcurse.org>
-rw-r--r--src/calcurse.h6
-rw-r--r--src/config.c7
-rw-r--r--src/custom.c2
-rw-r--r--src/pcal.c4
-rw-r--r--src/ui-calendar.c108
-rw-r--r--src/utils.c36
6 files changed, 82 insertions, 81 deletions
diff --git a/src/calcurse.h b/src/calcurse.h
index 8d9e3d8..db8dd51 100644
--- a/src/calcurse.h
+++ b/src/calcurse.h
@@ -152,7 +152,7 @@
* The argument (d) is the "Sunday"-numbering of member tm_wday in struct tm.
*/
#define WDAY(d) \
- (ui_calendar_week_begins_on_monday() ? ((d ? d : WEEKINDAYS) - 1) : d)
+ (modify_wday(d, -ui_calendar_get_wday_start()))
/* Key definitions. */
#define CTRLVAL 0x1F
@@ -811,7 +811,7 @@ void ui_calendar_set_current_date(void);
struct date *ui_calendar_get_today(void);
void ui_calendar_set_first_day_of_week(enum wday);
void ui_calendar_change_first_day_of_week(void);
-unsigned ui_calendar_week_begins_on_monday(void);
+int ui_calendar_get_wday_start(void);
void ui_calendar_store_current_date(struct date *);
void ui_calendar_init_slctd_day(void);
struct date *ui_calendar_get_slctd_day(void);
@@ -1234,6 +1234,8 @@ time_t date_sec_change(time_t, int, int);
time_t update_time_in_date(time_t, unsigned, unsigned);
time_t get_sec_date(struct date);
long min2sec(unsigned);
+int modify_wday(int,int);
+char *get_wday_default_string(int);
void draw_scrollbar(struct scrollwin *, int);
void item_in_popup(const char *, const char *, const char *, const char *);
time_t get_today(void);
diff --git a/src/config.c b/src/config.c
index b309c28..2df2559 100644
--- a/src/config.c
+++ b/src/config.c
@@ -468,10 +468,9 @@ static int config_serialize_default_panel(char **buf, void *dummy)
static int config_serialize_first_day_of_week(char **buf, void *dummy)
{
- if (ui_calendar_week_begins_on_monday())
- *buf = mem_strdup("monday");
- else
- *buf = mem_strdup("sunday");
+ *buf = mem_strdup(get_wday_default_string(ui_calendar_get_wday_start()));
+ /* now stores string with uppercase first letter, changing to lower */
+ **buf = tolower(**buf);
return 1;
}
diff --git a/src/custom.c b/src/custom.c
index 889772e..5f66194 100644
--- a/src/custom.c
+++ b/src/custom.c
@@ -702,7 +702,7 @@ static void print_general_option(int i, WINDOW *win, int y, int hilt, void *cb_d
case FIRST_DAY_OF_WEEK:
custom_apply_attr(win, ATTR_HIGHEST);
mvwaddstr(win, y, XPOS + strlen(opt[FIRST_DAY_OF_WEEK]),
- ui_calendar_week_begins_on_monday()? _("Monday") :
+ ui_calendar_get_wday_start()? _("Monday") :
_("Sunday"));
custom_remove_attr(win, ATTR_HIGHEST);
mvwaddstr(win, y + 1, XPOS,
diff --git a/src/pcal.c b/src/pcal.c
index 78da0bb..16c3b9f 100644
--- a/src/pcal.c
+++ b/src/pcal.c
@@ -102,8 +102,8 @@ static void pcal_export_header(FILE * stream)
{
fputs("# calcurse pcal export\n", stream);
fputs("\n# =======\n# options\n# =======\n", stream);
- fprintf(stream, "opt -A -K -l -m -F %s\n",
- ui_calendar_week_begins_on_monday()? "Monday" : "Sunday");
+ fprintf(stream, "opt -A -K -l -m -F %s\n", get_wday_default_string(
+ ui_calendar_get_wday_start()));
fputs("# Display week number (i.e. 1-52) on every Monday\n",
stream);
fprintf(stream, "all monday in all week %%w\n");
diff --git a/src/ui-calendar.c b/src/ui-calendar.c
index 4a8ef44..e4d5289 100644
--- a/src/ui-calendar.c
+++ b/src/ui-calendar.c
@@ -45,14 +45,14 @@
#include "calcurse.h"
static struct date today, slctd_day;
-static unsigned ui_calendar_view, week_begins_on_monday;
+static unsigned ui_calendar_view;
+static int wday_start; /* this is used in signed arithmetic */
static pthread_mutex_t date_thread_mutex = PTHREAD_MUTEX_INITIALIZER;
-static void draw_monthly_view(struct scrollwin *, struct date *, unsigned);
-static void draw_weekly_view(struct scrollwin *, struct date *, unsigned);
-static void (*draw_calendar[CAL_VIEWS]) (struct scrollwin *, struct date *,
- unsigned) = {
-draw_monthly_view, draw_weekly_view};
+static void draw_monthly_view(struct scrollwin *, struct date *);
+static void draw_weekly_view(struct scrollwin *, struct date *);
+static void (*draw_calendar[CAL_VIEWS]) (struct scrollwin *,
+ struct date *) = {draw_monthly_view, draw_weekly_view};
/* Six weeks cover a month. */
static int monthly_view_cache[WEEKINDAYS * 6];
@@ -148,30 +148,24 @@ struct date *ui_calendar_get_today(void)
/* 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:
+ if (first_day >= 0 && first_day <= 6)
+ wday_start = first_day;
+ else {
ERROR_MSG(_("ERROR setting first day of week"));
- week_begins_on_monday = 0;
- /* NOTREACHED */
+ wday_start = 0;
}
}
/* Swap first day of week in calendar. */
void ui_calendar_change_first_day_of_week(void)
{
- week_begins_on_monday = !week_begins_on_monday;
+ wday_start = !wday_start;
}
/* Return 1 if week begins on monday, 0 otherwise. */
-unsigned ui_calendar_week_begins_on_monday(void)
+int ui_calendar_get_wday_start(void)
{
- return week_begins_on_monday;
+ return wday_start;
}
/* Fill in the given variable with the current date. */
@@ -219,18 +213,14 @@ void ui_calendar_monthly_view_cache_set_invalid(void)
monthly_view_cache_valid = 0;
}
-static int weeknum(const struct tm *t, int firstweekday)
+static int weeknum(const struct tm *t, int wday_start)
{
int wday, wnum;
wday = t->tm_wday;
- if (firstweekday == MONDAY) {
- if (wday == SUNDAY)
- wday = 6;
- else
- wday--;
- }
- wnum = ((t->tm_yday + WEEKINDAYS - wday) / WEEKINDAYS);
+ wnum = ((t->tm_yday + WEEKINDAYS + -modify_wday(wday, -wday_start))
+ / WEEKINDAYS);
+
if (wnum < 0)
wnum = 0;
@@ -296,7 +286,7 @@ static int ISO8601weeknum(const struct tm *t)
* Return the tm structure for the first day of the first week
* (containing a day) of the selected month.
*/
-static struct tm get_first_day(unsigned sunday_first)
+static struct tm get_first_day(int wday_start)
{
struct tm t;
struct date d;
@@ -308,26 +298,20 @@ static struct tm get_first_day(unsigned sunday_first)
t = date2tm(d, 0, 0);
mktime(&t);
/* get the first day of the week */
- date_change(&t, 0,
- -(sunday_first ?
- t.tm_wday :
- (t.tm_wday + WEEKINDAYS - 1) % WEEKINDAYS));
+ date_change(&t, 0, -modify_wday(t.tm_wday, -wday_start));
+
return t;
}
-static struct tm get_first_weekday(unsigned sunday_first)
+static struct tm get_first_weekday(int wday_start)
{
- int c_wday, days_to_remove;
+ int c_wday;
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);
+
+ date_change(&t, 0, -modify_wday(c_wday, -wday_start));
return t;
}
@@ -346,8 +330,7 @@ static void draw_week_number(struct scrollwin *sw, struct tm t)
/* Draw the monthly view inside calendar panel. */
static void
-draw_monthly_view(struct scrollwin *sw, struct date *current_day,
- unsigned sunday_first)
+draw_monthly_view(struct scrollwin *sw, struct date *current_day)
{
struct date c_day;
int slctd, w_day, numdays, j, week = 0;
@@ -373,7 +356,7 @@ draw_monthly_view(struct scrollwin *sw, struct date *current_day,
* Step forward by week until past the last day of the month.
* The first day of the first week may belong to the previous month.
*/
- t = t_first = get_first_day(sunday_first);
+ t = t_first = get_first_day(wday_start);
t.tm_mday += WEEKINDAYS;
mktime(&t);
last_day += WEEKINDAYS;
@@ -423,7 +406,7 @@ draw_monthly_view(struct scrollwin *sw, struct date *current_day,
custom_apply_attr(sw->inner, ATTR_HIGHEST);
for (j = 0; j < WEEKINDAYS; j++) {
mvwaddstr(sw->inner, ofs_y, ofs_x + weekw + 4 * j,
- nl_langinfo(ABDAY_1 + (1 + j - sunday_first) % WEEKINDAYS));
+ nl_langinfo(ABDAY_1 + modify_wday(j, wday_start)));
}
custom_remove_attr(sw->inner, ATTR_HIGHEST);
WINS_CALENDAR_UNLOCK;
@@ -449,11 +432,9 @@ draw_monthly_view(struct scrollwin *sw, struct date *current_day,
if (j == first_day ||
(mo == 1 && j == WEEKINDAYS) ||
(mo == 12 && j >= 4 * WEEKINDAYS)) {
- if (sunday_first)
- date_change(&t, 0, 1);
+ date_change(&t, 0, WDAY(MONDAY));
week = ISO8601weeknum(&t);
- if (sunday_first)
- date_change(&t, 0, -1);
+ date_change(&t, 0, -WDAY(MONDAY));
} else
week++;
}
@@ -506,8 +487,7 @@ draw_monthly_view(struct scrollwin *sw, struct date *current_day,
/* Draw the weekly view inside calendar panel. */
static void
-draw_weekly_view(struct scrollwin *sw, struct date *current_day,
- unsigned sunday_first)
+draw_weekly_view(struct scrollwin *sw, struct date *current_day)
{
#define DAYSLICESNO 6
const int WCALWIDTH = 28;
@@ -520,14 +500,14 @@ draw_weekly_view(struct scrollwin *sw, struct date *current_day,
OFFX = (wins_sbar_width() - 2 - WCALWIDTH) / 2;
/* Print the week number, calculated from monday. */
- t = get_first_weekday(0);
+ t = get_first_weekday(MONDAY);
draw_week_number(sw, t);
/* Now draw calendar view. */
for (j = 0; j < WEEKINDAYS; j++) {
/* get next day */
if (j == 0)
- t = get_first_weekday(sunday_first);
+ t = get_first_weekday(wday_start);
else
date_change(&t, 0, 1);
@@ -538,7 +518,7 @@ draw_weekly_view(struct scrollwin *sw, struct date *current_day,
/* print the day names, with regards to the first day of the week */
custom_apply_attr(sw->inner, ATTR_HIGHEST);
mvwaddstr(sw->inner, OFFY, OFFX + 4 * j,
- nl_langinfo(ABDAY_1 + (1 + j - sunday_first) % WEEKINDAYS));
+ nl_langinfo(ABDAY_1 + modify_wday(j, wday_start)));
custom_remove_attr(sw->inner, ATTR_HIGHEST);
/* Check if the day to be printed has an item or not. */
@@ -624,11 +604,9 @@ draw_weekly_view(struct scrollwin *sw, struct date *current_day,
void ui_calendar_update_panel(void)
{
struct date current_day;
- unsigned sunday_first;
ui_calendar_store_current_date(&current_day);
- sunday_first = !ui_calendar_week_begins_on_monday();
- draw_calendar[ui_calendar_view] (&sw_cal, &current_day, sunday_first);
+ draw_calendar[ui_calendar_view] (&sw_cal, &current_day);
wins_scrollwin_display(&sw_cal, NOHILT);
}
@@ -728,28 +706,14 @@ void ui_calendar_move(enum move move, int count)
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 = WDAY(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 = modify_wday(-t.tm_wday, wday_start - 1);
days_to_add += (count - 1) * WEEKINDAYS;
ret = date_change(&t, 0, days_to_add);
break;
diff --git a/src/utils.c b/src/utils.c
index 1a480df..f631c8c 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -626,6 +626,42 @@ long min2sec(unsigned minutes)
return minutes * MININSEC;
}
+int modify_wday(int wday, int shift)
+{
+ return (WEEKINDAYS + wday + shift) % WEEKINDAYS;
+}
+
+/* returns char* representing a wday, used for internal functions */
+char *get_wday_default_string(int wday)
+{
+ switch(wday) {
+ case MONDAY:
+ return "Monday";
+ break;
+ case TUESDAY:
+ return "Tuesday";
+ break;
+ case WEDNESDAY:
+ return "Wednesday";
+ break;
+ case THURSDAY:
+ return "Thursday";
+ break;
+ case FRIDAY:
+ return "Friday";
+ break;
+ case SATURDAY:
+ return "Saturday";
+ break;
+ case SUNDAY:
+ return "Sunday";
+ break;
+ default:
+ return "Sunday";
+ break;
+ }
+}
+
/*
* Display a scroll bar when there are so many items that they
* can not be displayed inside the corresponding panel.