[california/wip/first-of-week: 4/4] Calendar.System.first_of_week



commit 73eea7edf0740aa2e8e77c6b5baebde2e0a00c71
Author: Jim Nelson <jim yorba org>
Date:   Fri Jun 13 15:25:58 2014 -0700

    Calendar.System.first_of_week

 src/application/california-settings.vala |   30 ++++++++++++++-----------
 src/calendar/calendar-system.vala        |   35 ++++++++++++++++++++++++++++++
 src/view/month/month-cell.vala           |    8 +++---
 src/view/month/month-controller.vala     |    8 +++---
 src/view/month/month-grid.vala           |    8 +++---
 src/view/week/week-all-day-cell.vala     |    8 +++---
 src/view/week/week-controller.vala       |   14 ++++++------
 7 files changed, 75 insertions(+), 36 deletions(-)
---
diff --git a/src/application/california-settings.vala b/src/application/california-settings.vala
index 91856d2..55d4986 100644
--- a/src/application/california-settings.vala
+++ b/src/application/california-settings.vala
@@ -17,7 +17,6 @@ public class Settings : BaseObject {
     public const string PROP_WINDOW_WIDTH = "window-width";
     public const string PROP_WINDOW_HEIGHT = "window-height";
     public const string PROP_WINDOW_MAXIMIZED = "window-maximized";
-    public const string PROP_FIRST_OF_WEEK = "first-of-week";
     
     // GSettings schema identifier.
     private const string SCHEMA_ID = "org.yorba.california";
@@ -111,11 +110,6 @@ public class Settings : BaseObject {
      */
     public bool window_maximized { get; set; }
     
-    /**
-     * Configured first day of the week.
-     */
-    public Calendar.FirstOfWeek first_of_week { get; set; }
-    
     private GLib.Settings settings;
     
     private Settings() {
@@ -129,12 +123,16 @@ public class Settings : BaseObject {
         
         // bind_mapping() isn't well-bound in the VAPI, so do some of these transformations manually
         settings.changed.connect(on_setting_changed);
-        notify[PROP_FIRST_OF_WEEK].connect(on_property_first_of_week_changed);
+        Calendar.System.instance.first_of_week_changed.connect(on_system_first_of_week_changed);
         
         // initialize these unbound values
         on_setting_changed(KEY_FIRST_OF_WEEK);
     }
     
+    ~Settings() {
+        Calendar.System.instance.first_of_week_changed.disconnect(on_system_first_of_week_changed);
+    }
+    
     internal static void init() throws Error {
         // this needs to be available before initialization
         assert(Application.instance.exec_file != null);
@@ -145,11 +143,16 @@ public class Settings : BaseObject {
             Environment.set_variable("GSETTINGS_SCHEMA_DIR", schema_dir.get_path(), true);
         }
         
+        // Calendar must be initialized for Settings to set/monitor first-of-week
+        Calendar.init();
+        
         instance = new Settings();
     }
     
     internal static void terminate() {
         instance = null;
+        
+        Calendar.terminate();
     }
     
     private void on_setting_changed(string key) {
@@ -176,14 +179,15 @@ public class Settings : BaseObject {
             break;
         }
         
-        // to avoid unnecessary notifications
-        if (first_of_week != to_set)
-            first_of_week = to_set;
+        // prevent notification loops
+        if (Calendar.System.first_of_week != to_set)
+            Calendar.System.first_of_week = to_set;
     }
     
-    private void on_property_first_of_week_changed() {
+    private void on_system_first_of_week_changed(Calendar.FirstOfWeek old_fow,
+        Calendar.FirstOfWeek new_fow) {
         string value;
-        switch (first_of_week) {
+        switch (new_fow) {
             case Calendar.FirstOfWeek.MONDAY:
                 value = VALUE_FIRST_OF_WEEK_MONDAY;
             break;
@@ -196,7 +200,7 @@ public class Settings : BaseObject {
                 assert_not_reached();
         }
         
-        // prevent costly writes
+        // prevent costly writes and notification loops
         if (settings.get_string(KEY_FIRST_OF_WEEK).casefold() != value)
             settings.set_string(KEY_FIRST_OF_WEEK, value);
     }
diff --git a/src/calendar/calendar-system.vala b/src/calendar/calendar-system.vala
index 090d695..b43d80d 100644
--- a/src/calendar/calendar-system.vala
+++ b/src/calendar/calendar-system.vala
@@ -60,6 +60,36 @@ public class System : BaseObject {
      */
     public static Timezone timezone { get; private set; }
     
+    /**
+     * The user's preferred start of the week.
+     *
+     * Unlike most of the other properties here (which are determined by examining and monitoring
+     * the system), this is strictly a user preference that should be configured by the outer
+     * application.  It's store here because it's something that many components in { link Calendar}
+     * need access to and passing it around is often inconvenient.  However, many of the "basic"
+     * classes (such as { link Date} and { link DayOfWeek}) still ask for it as a parameter to
+     * remain flexible.  In the case of { link Week}, it ''must'' store it, as its span of days is
+     * strictly determined by the decision, which can change at runtime.
+     *
+     * @see first_of_week_changed
+     */
+    private static FirstOfWeek _first_of_week = FirstOfWeek.DEFAULT;
+    public static FirstOfWeek first_of_week {
+        get {
+            return _first_of_week;
+        }
+        
+        set {
+            if (_first_of_week == value)
+                return;
+            
+            FirstOfWeek old_fow = _first_of_week;
+            _first_of_week = value;
+            
+            instance.first_of_week_changed(old_fow, _first_of_week);
+        }
+    }
+    
     private static DBus.timedated timedated_service;
     private static DBus.Properties timedated_properties;
     
@@ -91,6 +121,11 @@ public class System : BaseObject {
      */
     public signal void timezone_changed(Timezone old_timezone, Timezone new_timezone);
     
+    /**
+     * Fired when { link first_of_week} changes due to user configuration.
+     */
+    public signal void first_of_week_changed(FirstOfWeek old_fow, FirstOfWeek new_fow);
+    
     private GLib.Settings system_clock_format_schema = new GLib.Settings(CLOCK_FORMAT_SCHEMA);
     private uint date_timer_id = 0;
     
diff --git a/src/view/month/month-cell.vala b/src/view/month/month-cell.vala
index d4242d1..ef76d81 100644
--- a/src/view/month/month-cell.vala
+++ b/src/view/month/month-cell.vala
@@ -18,7 +18,7 @@ internal class Cell : Common.EventsCell {
     public int col { get; private set; }
     
     public Cell(Grid owner, Calendar.Date date, int row, int col) {
-        base (owner.owner.palette, date, date.week_of(Settings.instance.first_of_week).to_date_span());
+        base (owner.owner.palette, date, date.week_of(Calendar.System.first_of_week).to_date_span());
         
         this.owner = owner;
         this.row = row;
@@ -26,13 +26,13 @@ internal class Cell : Common.EventsCell {
         
         notify[PROP_DATE].connect(update_top_line);
         
-        Settings.instance.notify[Settings.PROP_FIRST_OF_WEEK].connect(on_first_of_week_changed);
+        Calendar.System.instance.first_of_week_changed.connect(on_first_of_week_changed);
         
         update_top_line();
     }
     
     ~Cell() {
-        Settings.instance.notify[Settings.PROP_FIRST_OF_WEEK].disconnect(on_first_of_week_changed);
+        Calendar.System.instance.first_of_week_changed.disconnect(on_first_of_week_changed);
     }
     
     protected override Common.EventsCell? get_cell_for_date(Calendar.Date cell_date) {
@@ -40,7 +40,7 @@ internal class Cell : Common.EventsCell {
     }
     
     private void on_first_of_week_changed() {
-        change_date_and_neighbors(date, date.week_of(Settings.instance.first_of_week).to_date_span());
+        change_date_and_neighbors(date, date.week_of(Calendar.System.first_of_week).to_date_span());
     }
     
     protected override void draw_borders(Cairo.Context ctx) {
diff --git a/src/view/month/month-controller.vala b/src/view/month/month-controller.vala
index 268078a..78a47cf 100644
--- a/src/view/month/month-controller.vala
+++ b/src/view/month/month-controller.vala
@@ -98,7 +98,7 @@ public class Controller : BaseObject, View.Controllable {
             dow_label.margin_top = 2;
             dow_label.margin_bottom = 2;
             dow_label.label = Calendar.DayOfWeek.for_checked(col + 1,
-                Settings.instance.first_of_week).abbrev_name;
+                Calendar.System.first_of_week).abbrev_name;
             
             dow_labels.set(col, dow_label);
             
@@ -111,7 +111,7 @@ public class Controller : BaseObject, View.Controllable {
         
         notify[PROP_MONTH_OF_YEAR].connect(on_month_of_year_changed);
         Calendar.System.instance.today_changed.connect(on_today_changed);
-        Settings.instance.notify[Settings.PROP_FIRST_OF_WEEK].connect(on_first_of_week_changed);
+        Calendar.System.instance.first_of_week_changed.connect(on_first_of_week_changed);
         
         // update now that signal handlers are in place
         month_of_year = Calendar.System.today.month_of_year();
@@ -119,7 +119,7 @@ public class Controller : BaseObject, View.Controllable {
     
     ~Controller() {
         Calendar.System.instance.today_changed.disconnect(on_today_changed);
-        Settings.instance.notify[Settings.PROP_FIRST_OF_WEEK].disconnect(on_first_of_week_changed);
+        Calendar.System.instance.first_of_week_changed.disconnect(on_first_of_week_changed);
     }
     
     private Gtk.Widget model_presentation(Calendar.MonthOfYear moy, out string? id) {
@@ -206,7 +206,7 @@ public class Controller : BaseObject, View.Controllable {
         Gee.MapIterator<int, Gtk.Label> iter = dow_labels.map_iterator();
         while (iter.next()) {
             Calendar.DayOfWeek dow = Calendar.DayOfWeek.for_checked(iter.get_key() + 1,
-                Settings.instance.first_of_week);
+                Calendar.System.first_of_week);
             iter.get_value().label = dow.abbrev_name;
         }
     }
diff --git a/src/view/month/month-grid.vala b/src/view/month/month-grid.vala
index 624e563..eb59f54 100644
--- a/src/view/month/month-grid.vala
+++ b/src/view/month/month-grid.vala
@@ -89,12 +89,12 @@ private class Grid : Gtk.Grid {
         update_subscriptions();
         
         owner.notify[Controller.PROP_MONTH_OF_YEAR].connect(on_controller_month_of_year_changed);
-        Settings.instance.notify[Settings.PROP_FIRST_OF_WEEK].connect(update_first_of_week);
+        Calendar.System.instance.first_of_week_changed.connect(update_first_of_week);
     }
     
     ~Grid() {
         owner.notify[Controller.PROP_MONTH_OF_YEAR].disconnect(on_controller_month_of_year_changed);
-        Settings.instance.notify[Settings.PROP_FIRST_OF_WEEK].disconnect(update_first_of_week);
+        Calendar.System.instance.first_of_week_changed.disconnect(update_first_of_week);
     }
     
     private Cell get_cell(int row, int col) {
@@ -150,7 +150,7 @@ private class Grid : Gtk.Grid {
     private void update_week(int row, Calendar.Week week) {
         Calendar.DateSpan week_as_date_span = week.to_date_span();
         foreach (Calendar.Date date in week) {
-            int col = date.day_of_week.ordinal(Settings.instance.first_of_week) - 1;
+            int col = date.day_of_week.ordinal(Calendar.System.first_of_week) - 1;
             
             Cell cell = get_cell(row, col);
             cell.change_date_and_neighbors(date, week_as_date_span);
@@ -167,7 +167,7 @@ private class Grid : Gtk.Grid {
         // create a WeekSpan for the first week of the month to the last displayed week (not all
         // months will fill all displayed weeks, but some will)
         Calendar.WeekSpan span = new Calendar.WeekSpan.count(
-            month_of_year.to_week_span(Settings.instance.first_of_week).first, ROWS - 1);
+            month_of_year.to_week_span(Calendar.System.first_of_week).first, ROWS - 1);
         
         // fill in weeks of the displayed month
         int row = 0;
diff --git a/src/view/week/week-all-day-cell.vala b/src/view/week/week-all-day-cell.vala
index 7f48d53..3598846 100644
--- a/src/view/week/week-all-day-cell.vala
+++ b/src/view/week/week-all-day-cell.vala
@@ -20,11 +20,11 @@ internal class AllDayCell : Common.EventsCell {
     public Grid owner { get; private set; }
     
     public AllDayCell(Grid owner, Calendar.Date date) {
-        base (owner.owner.palette, date, date.week_of(Settings.instance.first_of_week).to_date_span());
+        base (owner.owner.palette, date, date.week_of(Calendar.System.first_of_week).to_date_span());
         
         this.owner = owner;
         
-        Settings.instance.notify[Settings.PROP_FIRST_OF_WEEK].connect(on_first_of_week_changed);
+        Calendar.System.instance.first_of_week_changed.connect(on_first_of_week_changed);
         palette.palette_changed.connect(on_palette_changed);
         
         // use for initialization
@@ -32,7 +32,7 @@ internal class AllDayCell : Common.EventsCell {
     }
     
     ~AllDayCell() {
-        Settings.instance.notify[Settings.PROP_FIRST_OF_WEEK].disconnect(on_first_of_week_changed);
+        Calendar.System.instance.first_of_week_changed.disconnect(on_first_of_week_changed);
         palette.palette_changed.disconnect(on_palette_changed);
     }
     
@@ -46,7 +46,7 @@ internal class AllDayCell : Common.EventsCell {
     }
     
     private void on_first_of_week_changed() {
-        change_date_and_neighbors(date, date.week_of(Settings.instance.first_of_week).to_date_span());
+        change_date_and_neighbors(date, date.week_of(Calendar.System.first_of_week).to_date_span());
     }
     
     protected override void draw_borders(Cairo.Context ctx) {
diff --git a/src/view/week/week-controller.vala b/src/view/week/week-controller.vala
index fd636a1..d3496d6 100644
--- a/src/view/week/week-controller.vala
+++ b/src/view/week/week-controller.vala
@@ -72,15 +72,15 @@ public class Controller : BaseObject, View.Controllable {
             trim_presentation_from_cache, ensure_presentation_in_cache);
         
         // changing these properties drives a lot of the what the view displays
-        Settings.instance.notify[Settings.PROP_FIRST_OF_WEEK].connect(on_first_of_week_changed);
+        Calendar.System.instance.first_of_week_changed.connect(on_first_of_week_changed);
         notify[PROP_WEEK].connect(on_week_changed);
         
         // set this now that signal handlers are in place
-        week = Calendar.System.today.week_of(Settings.instance.first_of_week);
+        week = Calendar.System.today.week_of(Calendar.System.first_of_week);
     }
     
     ~Controller() {
-        Settings.instance.notify[Settings.PROP_FIRST_OF_WEEK].disconnect(on_first_of_week_changed);
+        Calendar.System.instance.first_of_week_changed.disconnect(on_first_of_week_changed);
     }
     
     /**
@@ -108,7 +108,7 @@ public class Controller : BaseObject, View.Controllable {
      * @inheritDoc
      */
     public void today() {
-        Calendar.Week this_week = Calendar.System.today.week_of(Settings.instance.first_of_week);
+        Calendar.Week this_week = Calendar.System.today.week_of(Calendar.System.first_of_week);
         if (!week.equal_to(this_week))
             week = this_week;
     }
@@ -135,7 +135,7 @@ public class Controller : BaseObject, View.Controllable {
     
     private bool trim_presentation_from_cache(Calendar.Week week, Calendar.Week? visible_week) {
         // always keep today's week in cache
-        if (week.equal_to(Calendar.System.today.week_of(Settings.instance.first_of_week)))
+        if (week.equal_to(Calendar.System.today.week_of(Calendar.System.first_of_week)))
             return false;
         
         // otherwise only keep weeks that are in the current cache span
@@ -147,14 +147,14 @@ public class Controller : BaseObject, View.Controllable {
         Gee.List<Calendar.Week> weeks = cache_span.as_list();
         
         // add today's week to the mix
-        weeks.add(Calendar.System.today.week_of(Settings.instance.first_of_week));
+        weeks.add(Calendar.System.today.week_of(Calendar.System.first_of_week));
         
         return weeks;
     }
     
     private void on_first_of_week_changed() {
         stack_model.clear();
-        week = week.start_date.week_of(Settings.instance.first_of_week);
+        week = week.start_date.week_of(Calendar.System.first_of_week);
     }
     
     private void on_week_changed() {


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