From 66fa49b1669711bf1732d3e5b4b0bef3d8dc06c3 Mon Sep 17 00:00:00 2001 From: Carlo Lobrano Date: Sun, 23 Jul 2017 22:59:03 +0200 Subject: [PATCH] year-view: Mark working days according to locale Currently, on the year view, Saturday and Sunday are marked as non working days by default, despite the Locale settings and the fact that in some Countries Sunday and/or Saturday are workdays. This patch introduces a new function "is_workday" to check whether a day is a working day according to the territory part of Locale. https://bugzilla.gnome.org/show_bug.cgi?id=746927 --- data/theme/gtk-styles.css | 4 +- src/gcal-utils.c | 84 ++++++++++++++++++++++++++++++++++++++ src/gcal-utils.h | 14 +++++++ src/views/gcal-year-view.c | 13 +++--- 4 files changed, 107 insertions(+), 8 deletions(-) diff --git a/data/theme/gtk-styles.css b/data/theme/gtk-styles.css index d53f784f..6f614c14 100644 --- a/data/theme/gtk-styles.css +++ b/data/theme/gtk-styles.css @@ -89,7 +89,7 @@ calendar-view.offset { font-size: 9pt; } -.year-navigator.sunday { +.year-navigator.non-workday { color: alpha(@theme_fg_color, 0.5); } @@ -132,7 +132,7 @@ calendar-view.offset { background-color: @theme_selected_bg_color; } -.year-navigator.with-events-sunday { +.year-navigator.with-events-non-workday { background-color: alpha(@theme_fg_color, 0.5); } diff --git a/src/gcal-utils.c b/src/gcal-utils.c index 9d27c4be..7e369f42 100644 --- a/src/gcal-utils.c +++ b/src/gcal-utils.c @@ -35,6 +35,7 @@ #include #include +#include /** * SECTION:gcal-utils @@ -1230,3 +1231,86 @@ ask_recurrence_modification_type (GtkWidget *parent, return is_set; } + +struct +{ + const gchar *territory; + GcalWeekDay no_work_days; +} no_work_day_per_locale[] = { + { "AE", GCAL_WEEK_DAY_FRIDAY | GCAL_WEEK_DAY_SATURDAY } /* United Arab Emirates */, + { "AF", GCAL_WEEK_DAY_FRIDAY | GCAL_WEEK_DAY_SATURDAY } /* Afghanistan */, + { "BD", GCAL_WEEK_DAY_FRIDAY | GCAL_WEEK_DAY_SATURDAY } /* Bangladesh */, + { "BH", GCAL_WEEK_DAY_FRIDAY | GCAL_WEEK_DAY_SATURDAY } /* Bahrain */, + { "BN", GCAL_WEEK_DAY_SUNDAY | GCAL_WEEK_DAY_FRIDAY } /* Brunei Darussalam */, + { "CR", GCAL_WEEK_DAY_SATURDAY } /* Costa Rica */, + { "DJ", GCAL_WEEK_DAY_FRIDAY } /* Djibouti */, + { "DZ", GCAL_WEEK_DAY_FRIDAY | GCAL_WEEK_DAY_SATURDAY } /* Algeria */, + { "EG", GCAL_WEEK_DAY_FRIDAY | GCAL_WEEK_DAY_SATURDAY } /* Egypt */, + { "GN", GCAL_WEEK_DAY_SATURDAY } /* Equatorial Guinea */, + { "HK", GCAL_WEEK_DAY_SATURDAY } /* Hong Kong */, + { "IL", GCAL_WEEK_DAY_FRIDAY | GCAL_WEEK_DAY_SATURDAY } /* Israel */, + { "IQ", GCAL_WEEK_DAY_FRIDAY | GCAL_WEEK_DAY_SATURDAY } /* Iraq */, + { "IR", GCAL_WEEK_DAY_THURSDAY | GCAL_WEEK_DAY_FRIDAY } /* Iran */, + { "KW", GCAL_WEEK_DAY_FRIDAY | GCAL_WEEK_DAY_SATURDAY } /* Kuwait */, + { "KZ", GCAL_WEEK_DAY_FRIDAY | GCAL_WEEK_DAY_SATURDAY } /* Kazakhstan */, + { "LY", GCAL_WEEK_DAY_FRIDAY | GCAL_WEEK_DAY_SATURDAY } /* Libya */, + { "MX", GCAL_WEEK_DAY_SATURDAY } /* Mexico */, + { "MY", GCAL_WEEK_DAY_FRIDAY | GCAL_WEEK_DAY_SATURDAY } /* Malaysia */, + { "NP", GCAL_WEEK_DAY_SATURDAY } /* Nepal */, + { "OM", GCAL_WEEK_DAY_FRIDAY | GCAL_WEEK_DAY_SATURDAY } /* Oman */, + { "QA", GCAL_WEEK_DAY_FRIDAY | GCAL_WEEK_DAY_SATURDAY } /* Qatar */, + { "SA", GCAL_WEEK_DAY_FRIDAY | GCAL_WEEK_DAY_SATURDAY } /* Saudi Arabia */, + { "SU", GCAL_WEEK_DAY_FRIDAY | GCAL_WEEK_DAY_SATURDAY } /* Sudan */, + { "SY", GCAL_WEEK_DAY_FRIDAY | GCAL_WEEK_DAY_SATURDAY } /* Syria */, + { "UG", GCAL_WEEK_DAY_SUNDAY } /* Uganda */, + { "YE", GCAL_WEEK_DAY_FRIDAY | GCAL_WEEK_DAY_SATURDAY } /* Yemen */, +}; + + +/** + * is_workday: + * @day: a guint representing the day of a week (0…Sunday, 6…Saturday) + * + * Checks whether @day is workday or not based on the Territory part of Locale. + * + * Returns: %TRUE if @day is a workday, %FALSE otherwise. + */ +gboolean +is_workday (guint day) +{ + GcalWeekDay no_work_days; + gchar *locale; + gchar territory[3] = { 0, }; + guint i; + + if (day > 6) + return FALSE; + + no_work_days = GCAL_WEEK_DAY_SATURDAY | GCAL_WEEK_DAY_SUNDAY; + + locale = getenv ("LC_ALL"); + if (!locale || g_utf8_strlen (locale, -1) < 5) + locale = getenv ("LC_TIME"); + + if (!locale) + { + g_warning ("Locale is NULL, assuming Saturday and Sunday as non workdays"); + return !(no_work_days & 1 << day); + } + + g_return_val_if_fail (g_utf8_strlen (locale, -1) >= 5, TRUE); + + territory[0] = locale[3]; + territory[1] = locale[4]; + + for (i = 0; i < G_N_ELEMENTS (no_work_day_per_locale); i++) + { + if (g_strcmp0 (territory, no_work_day_per_locale[i].territory) == 0) + { + no_work_days = no_work_day_per_locale[i].no_work_days; + break; + } + } + + return !(no_work_days & 1 << day); +} diff --git a/src/gcal-utils.h b/src/gcal-utils.h index 96e91560..0e846d9b 100644 --- a/src/gcal-utils.h +++ b/src/gcal-utils.h @@ -54,6 +54,18 @@ typedef enum GCAL_WINDOW_VIEW_SEARCH, } GcalWindowViewType; +typedef enum +{ + GCAL_WEEK_DAY_INVALID = 0, + GCAL_WEEK_DAY_SUNDAY = 1 << 0, + GCAL_WEEK_DAY_MONDAY = 1 << 1, + GCAL_WEEK_DAY_TUESDAY = 1 << 2, + GCAL_WEEK_DAY_WEDNESDAY = 1 << 3, + GCAL_WEEK_DAY_THURSDAY = 1 << 4, + GCAL_WEEK_DAY_FRIDAY = 1 << 5, + GCAL_WEEK_DAY_SATURDAY = 1 << 6 +} GcalWeekDay; + GType icaltime_get_type (void) G_GNUC_CONST; gint datetime_compare_date (GDateTime *dt1, @@ -143,4 +155,6 @@ gboolean ask_recurrence_modification_type (GtkWidget ECalObjModType *modtype, ESource *source); +gboolean is_workday (guint day); + #endif // __GCAL_UTILS_H__ diff --git a/src/views/gcal-year-view.c b/src/views/gcal-year-view.c index 218c773a..164ff0f1 100644 --- a/src/views/gcal-year-view.c +++ b/src/views/gcal-year-view.c @@ -754,8 +754,9 @@ draw_month_grid (GcalYearView *year_view, GdkRGBA color; gint layout_width, layout_height, i, j, sw; gint column, row; + gboolean column_is_workday; gdouble x, y, box_side, box_padding_top, box_padding_start; - gint days_delay, days, shown_rows, sunday_idx; + gint days_delay, days, shown_rows; gchar *str, *nr_day, *nr_week; gboolean selected_day; icaltimetype today; @@ -824,7 +825,6 @@ draw_month_grid (GcalYearView *year_view, days_delay = (time_day_of_week (1, month_nr, year_view->date->year) - year_view->first_weekday + 7) % 7; days = days_delay + icaltime_days_in_month (month_nr + 1, year_view->date->year); shown_rows = ceil (days / 7.0); - sunday_idx = year_view->k * 7 + sw * ((7 - year_view->first_weekday) % 7) + year_view->show_week_numbers * (1 - year_view->k); today = icaltime_today (); today.year = year_view->date->year; @@ -838,6 +838,7 @@ draw_month_grid (GcalYearView *year_view, for (i = 0; i < 7 * shown_rows; i++) { column = (i % 7) + (year_view->k || year_view->show_week_numbers); + column_is_workday = is_workday ((7 * year_view->k + sw * (column - (year_view->show_week_numbers * !year_view->k) + (sw * year_view->first_weekday))) % 7); row = i / 7; j = 7 * ((i + 7 * year_view->k) / 7) + sw * (i % 7) + (1 - year_view->k); @@ -966,10 +967,10 @@ draw_month_grid (GcalYearView *year_view, gtk_style_context_set_state (context, state_flags); } - else if (column == sunday_idx) + else if (!column_is_workday) { gtk_style_context_save (context); - gtk_style_context_add_class (context, "sunday"); + gtk_style_context_add_class (context, "non-workday"); gtk_render_layout (context, cr, box_side * column + x + sw * box_padding_start - year_view->k * layout_width, box_side * (row + 1) + y + box_padding_top, @@ -994,8 +995,8 @@ draw_month_grid (GcalYearView *year_view, if (selected_day) gtk_style_context_add_class (context, "with-events-selected"); - else if (column == sunday_idx) - gtk_style_context_add_class (context, "with-events-sunday"); + else if (!column_is_workday) + gtk_style_context_add_class (context, "with-events-non-workday"); box_padding_start = MAX (0, (box_side - VISUAL_CLUES_SIDE) / 2); gtk_render_background (context, cr,