[gnome-calendar] year-view: Mark working days according to locale



commit 66fa49b1669711bf1732d3e5b4b0bef3d8dc06c3
Author: Carlo Lobrano <c lobrano gmail com>
Date:   Sun Jul 23 22:59:03 2017 +0200

    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 d53f784..6f614c1 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 9d27c4b..7e369f4 100644
--- a/src/gcal-utils.c
+++ b/src/gcal-utils.c
@@ -35,6 +35,7 @@
 
 #include <string.h>
 #include <math.h>
+#include <stdlib.h>
 
 /**
  * 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 96e9156..0e846d9 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 218c773..164ff0f 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,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]