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>
This commit is contained in:
parent
61ed5f835c
commit
e3fc73e0c7
@ -152,7 +152,7 @@
|
|||||||
* The argument (d) is the "Sunday"-numbering of member tm_wday in struct tm.
|
* The argument (d) is the "Sunday"-numbering of member tm_wday in struct tm.
|
||||||
*/
|
*/
|
||||||
#define WDAY(d) \
|
#define WDAY(d) \
|
||||||
(ui_calendar_week_begins_on_monday() ? ((d ? d : WEEKINDAYS) - 1) : d)
|
(modify_wday(d, -ui_calendar_get_wday_start()))
|
||||||
|
|
||||||
/* Key definitions. */
|
/* Key definitions. */
|
||||||
#define CTRLVAL 0x1F
|
#define CTRLVAL 0x1F
|
||||||
@ -811,7 +811,7 @@ void ui_calendar_set_current_date(void);
|
|||||||
struct date *ui_calendar_get_today(void);
|
struct date *ui_calendar_get_today(void);
|
||||||
void ui_calendar_set_first_day_of_week(enum wday);
|
void ui_calendar_set_first_day_of_week(enum wday);
|
||||||
void ui_calendar_change_first_day_of_week(void);
|
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_store_current_date(struct date *);
|
||||||
void ui_calendar_init_slctd_day(void);
|
void ui_calendar_init_slctd_day(void);
|
||||||
struct date *ui_calendar_get_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 update_time_in_date(time_t, unsigned, unsigned);
|
||||||
time_t get_sec_date(struct date);
|
time_t get_sec_date(struct date);
|
||||||
long min2sec(unsigned);
|
long min2sec(unsigned);
|
||||||
|
int modify_wday(int,int);
|
||||||
|
char *get_wday_default_string(int);
|
||||||
void draw_scrollbar(struct scrollwin *, int);
|
void draw_scrollbar(struct scrollwin *, int);
|
||||||
void item_in_popup(const char *, const char *, const char *, const char *);
|
void item_in_popup(const char *, const char *, const char *, const char *);
|
||||||
time_t get_today(void);
|
time_t get_today(void);
|
||||||
|
@ -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)
|
static int config_serialize_first_day_of_week(char **buf, void *dummy)
|
||||||
{
|
{
|
||||||
if (ui_calendar_week_begins_on_monday())
|
*buf = mem_strdup(get_wday_default_string(ui_calendar_get_wday_start()));
|
||||||
*buf = mem_strdup("monday");
|
/* now stores string with uppercase first letter, changing to lower */
|
||||||
else
|
**buf = tolower(**buf);
|
||||||
*buf = mem_strdup("sunday");
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -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:
|
case FIRST_DAY_OF_WEEK:
|
||||||
custom_apply_attr(win, ATTR_HIGHEST);
|
custom_apply_attr(win, ATTR_HIGHEST);
|
||||||
mvwaddstr(win, y, XPOS + strlen(opt[FIRST_DAY_OF_WEEK]),
|
mvwaddstr(win, y, XPOS + strlen(opt[FIRST_DAY_OF_WEEK]),
|
||||||
ui_calendar_week_begins_on_monday()? _("Monday") :
|
ui_calendar_get_wday_start()? _("Monday") :
|
||||||
_("Sunday"));
|
_("Sunday"));
|
||||||
custom_remove_attr(win, ATTR_HIGHEST);
|
custom_remove_attr(win, ATTR_HIGHEST);
|
||||||
mvwaddstr(win, y + 1, XPOS,
|
mvwaddstr(win, y + 1, XPOS,
|
||||||
|
@ -102,8 +102,8 @@ static void pcal_export_header(FILE * stream)
|
|||||||
{
|
{
|
||||||
fputs("# calcurse pcal export\n", stream);
|
fputs("# calcurse pcal export\n", stream);
|
||||||
fputs("\n# =======\n# options\n# =======\n", stream);
|
fputs("\n# =======\n# options\n# =======\n", stream);
|
||||||
fprintf(stream, "opt -A -K -l -m -F %s\n",
|
fprintf(stream, "opt -A -K -l -m -F %s\n", get_wday_default_string(
|
||||||
ui_calendar_week_begins_on_monday()? "Monday" : "Sunday");
|
ui_calendar_get_wday_start()));
|
||||||
fputs("# Display week number (i.e. 1-52) on every Monday\n",
|
fputs("# Display week number (i.e. 1-52) on every Monday\n",
|
||||||
stream);
|
stream);
|
||||||
fprintf(stream, "all monday in all week %%w\n");
|
fprintf(stream, "all monday in all week %%w\n");
|
||||||
|
@ -45,14 +45,14 @@
|
|||||||
#include "calcurse.h"
|
#include "calcurse.h"
|
||||||
|
|
||||||
static struct date today, slctd_day;
|
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 pthread_mutex_t date_thread_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
static void draw_monthly_view(struct scrollwin *, struct date *, unsigned);
|
static void draw_monthly_view(struct scrollwin *, struct date *);
|
||||||
static void draw_weekly_view(struct scrollwin *, struct date *, unsigned);
|
static void draw_weekly_view(struct scrollwin *, struct date *);
|
||||||
static void (*draw_calendar[CAL_VIEWS]) (struct scrollwin *, struct date *,
|
static void (*draw_calendar[CAL_VIEWS]) (struct scrollwin *,
|
||||||
unsigned) = {
|
struct date *) = {draw_monthly_view, draw_weekly_view};
|
||||||
draw_monthly_view, draw_weekly_view};
|
|
||||||
|
|
||||||
/* Six weeks cover a month. */
|
/* Six weeks cover a month. */
|
||||||
static int monthly_view_cache[WEEKINDAYS * 6];
|
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. */
|
/* 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)
|
void ui_calendar_set_first_day_of_week(enum wday first_day)
|
||||||
{
|
{
|
||||||
switch (first_day) {
|
if (first_day >= 0 && first_day <= 6)
|
||||||
case SUNDAY:
|
wday_start = first_day;
|
||||||
week_begins_on_monday = 0;
|
else {
|
||||||
break;
|
|
||||||
case MONDAY:
|
|
||||||
week_begins_on_monday = 1;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ERROR_MSG(_("ERROR setting first day of week"));
|
ERROR_MSG(_("ERROR setting first day of week"));
|
||||||
week_begins_on_monday = 0;
|
wday_start = 0;
|
||||||
/* NOTREACHED */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Swap first day of week in calendar. */
|
/* Swap first day of week in calendar. */
|
||||||
void ui_calendar_change_first_day_of_week(void)
|
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. */
|
/* 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. */
|
/* 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;
|
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;
|
int wday, wnum;
|
||||||
|
|
||||||
wday = t->tm_wday;
|
wday = t->tm_wday;
|
||||||
if (firstweekday == MONDAY) {
|
wnum = ((t->tm_yday + WEEKINDAYS + -modify_wday(wday, -wday_start))
|
||||||
if (wday == SUNDAY)
|
/ WEEKINDAYS);
|
||||||
wday = 6;
|
|
||||||
else
|
|
||||||
wday--;
|
|
||||||
}
|
|
||||||
wnum = ((t->tm_yday + WEEKINDAYS - wday) / WEEKINDAYS);
|
|
||||||
if (wnum < 0)
|
if (wnum < 0)
|
||||||
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
|
* Return the tm structure for the first day of the first week
|
||||||
* (containing a day) of the selected month.
|
* (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 tm t;
|
||||||
struct date d;
|
struct date d;
|
||||||
@ -308,26 +298,20 @@ static struct tm get_first_day(unsigned sunday_first)
|
|||||||
t = date2tm(d, 0, 0);
|
t = date2tm(d, 0, 0);
|
||||||
mktime(&t);
|
mktime(&t);
|
||||||
/* get the first day of the week */
|
/* get the first day of the week */
|
||||||
date_change(&t, 0,
|
date_change(&t, 0, -modify_wday(t.tm_wday, -wday_start));
|
||||||
-(sunday_first ?
|
|
||||||
t.tm_wday :
|
|
||||||
(t.tm_wday + WEEKINDAYS - 1) % WEEKINDAYS));
|
|
||||||
return t;
|
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;
|
struct tm t;
|
||||||
|
|
||||||
c_wday = ui_calendar_get_wday(&slctd_day);
|
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);
|
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;
|
return t;
|
||||||
}
|
}
|
||||||
@ -346,8 +330,7 @@ static void draw_week_number(struct scrollwin *sw, struct tm t)
|
|||||||
|
|
||||||
/* Draw the monthly view inside calendar panel. */
|
/* Draw the monthly view inside calendar panel. */
|
||||||
static void
|
static void
|
||||||
draw_monthly_view(struct scrollwin *sw, struct date *current_day,
|
draw_monthly_view(struct scrollwin *sw, struct date *current_day)
|
||||||
unsigned sunday_first)
|
|
||||||
{
|
{
|
||||||
struct date c_day;
|
struct date c_day;
|
||||||
int slctd, w_day, numdays, j, week = 0;
|
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.
|
* 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.
|
* 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;
|
t.tm_mday += WEEKINDAYS;
|
||||||
mktime(&t);
|
mktime(&t);
|
||||||
last_day += WEEKINDAYS;
|
last_day += WEEKINDAYS;
|
||||||
@ -423,7 +406,7 @@ draw_monthly_view(struct scrollwin *sw, struct date *current_day,
|
|||||||
custom_apply_attr(sw->inner, ATTR_HIGHEST);
|
custom_apply_attr(sw->inner, ATTR_HIGHEST);
|
||||||
for (j = 0; j < WEEKINDAYS; j++) {
|
for (j = 0; j < WEEKINDAYS; j++) {
|
||||||
mvwaddstr(sw->inner, ofs_y, ofs_x + weekw + 4 * 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);
|
custom_remove_attr(sw->inner, ATTR_HIGHEST);
|
||||||
WINS_CALENDAR_UNLOCK;
|
WINS_CALENDAR_UNLOCK;
|
||||||
@ -449,11 +432,9 @@ draw_monthly_view(struct scrollwin *sw, struct date *current_day,
|
|||||||
if (j == first_day ||
|
if (j == first_day ||
|
||||||
(mo == 1 && j == WEEKINDAYS) ||
|
(mo == 1 && j == WEEKINDAYS) ||
|
||||||
(mo == 12 && j >= 4 * WEEKINDAYS)) {
|
(mo == 12 && j >= 4 * WEEKINDAYS)) {
|
||||||
if (sunday_first)
|
date_change(&t, 0, WDAY(MONDAY));
|
||||||
date_change(&t, 0, 1);
|
|
||||||
week = ISO8601weeknum(&t);
|
week = ISO8601weeknum(&t);
|
||||||
if (sunday_first)
|
date_change(&t, 0, -WDAY(MONDAY));
|
||||||
date_change(&t, 0, -1);
|
|
||||||
} else
|
} else
|
||||||
week++;
|
week++;
|
||||||
}
|
}
|
||||||
@ -506,8 +487,7 @@ draw_monthly_view(struct scrollwin *sw, struct date *current_day,
|
|||||||
|
|
||||||
/* Draw the weekly view inside calendar panel. */
|
/* Draw the weekly view inside calendar panel. */
|
||||||
static void
|
static void
|
||||||
draw_weekly_view(struct scrollwin *sw, struct date *current_day,
|
draw_weekly_view(struct scrollwin *sw, struct date *current_day)
|
||||||
unsigned sunday_first)
|
|
||||||
{
|
{
|
||||||
#define DAYSLICESNO 6
|
#define DAYSLICESNO 6
|
||||||
const int WCALWIDTH = 28;
|
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;
|
OFFX = (wins_sbar_width() - 2 - WCALWIDTH) / 2;
|
||||||
|
|
||||||
/* Print the week number, calculated from monday. */
|
/* Print the week number, calculated from monday. */
|
||||||
t = get_first_weekday(0);
|
t = get_first_weekday(MONDAY);
|
||||||
draw_week_number(sw, t);
|
draw_week_number(sw, t);
|
||||||
|
|
||||||
/* Now draw calendar view. */
|
/* Now draw calendar view. */
|
||||||
for (j = 0; j < WEEKINDAYS; j++) {
|
for (j = 0; j < WEEKINDAYS; j++) {
|
||||||
/* get next day */
|
/* get next day */
|
||||||
if (j == 0)
|
if (j == 0)
|
||||||
t = get_first_weekday(sunday_first);
|
t = get_first_weekday(wday_start);
|
||||||
else
|
else
|
||||||
date_change(&t, 0, 1);
|
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 */
|
/* print the day names, with regards to the first day of the week */
|
||||||
custom_apply_attr(sw->inner, ATTR_HIGHEST);
|
custom_apply_attr(sw->inner, ATTR_HIGHEST);
|
||||||
mvwaddstr(sw->inner, OFFY, OFFX + 4 * j,
|
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);
|
custom_remove_attr(sw->inner, ATTR_HIGHEST);
|
||||||
|
|
||||||
/* Check if the day to be printed has an item or not. */
|
/* 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)
|
void ui_calendar_update_panel(void)
|
||||||
{
|
{
|
||||||
struct date current_day;
|
struct date current_day;
|
||||||
unsigned sunday_first;
|
|
||||||
|
|
||||||
ui_calendar_store_current_date(¤t_day);
|
ui_calendar_store_current_date(¤t_day);
|
||||||
sunday_first = !ui_calendar_week_begins_on_monday();
|
draw_calendar[ui_calendar_view] (&sw_cal, ¤t_day);
|
||||||
draw_calendar[ui_calendar_view] (&sw_cal, ¤t_day, sunday_first);
|
|
||||||
wins_scrollwin_display(&sw_cal, NOHILT);
|
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);
|
ret = date_change(&t, count * YEARINMONTHS, 0);
|
||||||
break;
|
break;
|
||||||
case WEEK_START:
|
case WEEK_START:
|
||||||
/* Normalize struct tm to get week day number. */
|
|
||||||
mktime(&t);
|
mktime(&t);
|
||||||
if (ui_calendar_week_begins_on_monday())
|
days_to_remove = WDAY(t.tm_wday);
|
||||||
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;
|
days_to_remove += (count - 1) * WEEKINDAYS;
|
||||||
ret = date_change(&t, 0, -days_to_remove);
|
ret = date_change(&t, 0, -days_to_remove);
|
||||||
break;
|
break;
|
||||||
case WEEK_END:
|
case WEEK_END:
|
||||||
mktime(&t);
|
mktime(&t);
|
||||||
if (ui_calendar_week_begins_on_monday())
|
days_to_add = modify_wday(-t.tm_wday, wday_start - 1);
|
||||||
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;
|
days_to_add += (count - 1) * WEEKINDAYS;
|
||||||
ret = date_change(&t, 0, days_to_add);
|
ret = date_change(&t, 0, days_to_add);
|
||||||
break;
|
break;
|
||||||
|
36
src/utils.c
36
src/utils.c
@ -626,6 +626,42 @@ long min2sec(unsigned minutes)
|
|||||||
return minutes * MININSEC;
|
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
|
* Display a scroll bar when there are so many items that they
|
||||||
* can not be displayed inside the corresponding panel.
|
* can not be displayed inside the corresponding panel.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user