[california] Default to system/locale's first day of week (Mon/Sun): Bug #734377
- From: Jim Nelson <jnelson src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [california] Default to system/locale's first day of week (Mon/Sun): Bug #734377
- Date: Thu, 7 Aug 2014 00:03:10 +0000 (UTC)
commit b402d5ae0719ce1b4443562eb21139a04024393c
Author: Jim Nelson <jim yorba org>
Date: Wed Aug 6 17:02:33 2014 -0700
Default to system/locale's first day of week (Mon/Sun): Bug #734377
configure.ac | 13 ++++
data/org.yorba.california.gschema.xml | 4 +-
src/Makefile.am | 7 ++-
src/application/california-settings.vala | 15 ++++-
src/calendar/calendar-first-of-week.vala | 9 +++-
src/calendar/calendar-system.vala | 82 ++++++++++++++++++++++--
vapi/langinfo.vapi | 100 ++++++++++++++++++++++++++++++
7 files changed, 219 insertions(+), 11 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index bee3010..5cbb475 100644
--- a/configure.ac
+++ b/configure.ac
@@ -54,6 +54,19 @@ AC_SUBST(CALIFORNIA_LIBS)
GLIB_GSETTINGS
#
+# system capabilities
+#
+
+# _NL_TIME_FIRST_WEEKDAY is an enum and not a define
+AC_MSG_CHECKING([for _NL_TIME_FIRST_WEEKDAY])
+AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <langinfo.h>]],
+ [[char c;
+ c = *((unsigned char *) nl_langinfo(_NL_TIME_FIRST_WEEKDAY));]])],
+ [california_ok=yes], [california_ok=no])
+AC_MSG_RESULT($california_ok)
+AM_CONDITIONAL(HAVE__NL_TIME_FIRST_WEEKDAY, test "$california_ok" = "yes")
+
+#
# configure switches
#
# Unity support
diff --git a/data/org.yorba.california.gschema.xml b/data/org.yorba.california.gschema.xml
index 5dfd453..123394a 100644
--- a/data/org.yorba.california.gschema.xml
+++ b/data/org.yorba.california.gschema.xml
@@ -48,10 +48,10 @@
</key>
<key name="first-of-week" type="s">
- <default>"sunday"</default>
+ <default>"system"</default>
<summary>The first day of the week</summary>
<description>
- For now, the only two respected values are "sunday" and "monday".
+ For now, the only respected values are "sunday", "monday", and "system".
</description>
</key>
</schema>
diff --git a/src/Makefile.am b/src/Makefile.am
index a858b9a..2f1d536 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -206,6 +206,10 @@ if IS_GTK_312
california_OPTIONAL_VALAFLAGS += --define GTK_312
endif
+if HAVE__NL_TIME_FIRST_WEEKDAY
+california_OPTIONAL_VALAFLAGS += --define HAVE__NL_TIME_FIRST_WEEKDAY
+endif
+
california_VALAFLAGS = \
--fatal-warnings --debug --enable-checking --vapidir $(top_srcdir)/vapi --target-glib=2.38 \
--enable-deprecated \
@@ -220,7 +224,8 @@ california_VALAFLAGS = \
--pkg libical \
--pkg libsoup-2.4 \
--pkg libgdata \
- --pkg=Goa-1.0 \
+ --pkg Goa-1.0 \
+ --pkg langinfo \
$(NULL)
california_CFLAGS = \
diff --git a/src/application/california-settings.vala b/src/application/california-settings.vala
index 55d4986..6eba4a9 100644
--- a/src/application/california-settings.vala
+++ b/src/application/california-settings.vala
@@ -33,6 +33,7 @@ public class Settings : BaseObject {
private const string VALUE_FIRST_OF_WEEK_SUNDAY = "sunday";
private const string VALUE_FIRST_OF_WEEK_MONDAY = "monday";
+ private const string VALUE_FIRST_OF_WEEK_SYSTEM = "system";
public static Settings instance { get; private set; }
@@ -155,6 +156,17 @@ public class Settings : BaseObject {
Calendar.terminate();
}
+ /**
+ * Reset settings to use system-defined (or locale-defined) first day of week.
+ *
+ * This is necessary because { link Settings} will monitor { link Calendar.System.first_of_week}
+ * for changes and save them to GSettings, but there's no way via that interface to specify
+ * "fall back on system's value".
+ */
+ public void use_system_first_of_week() {
+ settings.set_string(KEY_FIRST_OF_WEEK, VALUE_FIRST_OF_WEEK_SYSTEM);
+ }
+
private void on_setting_changed(string key) {
switch (key.casefold()) {
case KEY_FIRST_OF_WEEK:
@@ -174,8 +186,9 @@ public class Settings : BaseObject {
to_set = Calendar.FirstOfWeek.SUNDAY;
break;
+ case VALUE_FIRST_OF_WEEK_SYSTEM:
default:
- to_set = Calendar.FirstOfWeek.DEFAULT;
+ to_set = Calendar.System.instance.system_first_of_week;
break;
}
diff --git a/src/calendar/calendar-first-of-week.vala b/src/calendar/calendar-first-of-week.vala
index ed87f5e..f164125 100644
--- a/src/calendar/calendar-first-of-week.vala
+++ b/src/calendar/calendar-first-of-week.vala
@@ -16,8 +16,11 @@ public enum FirstOfWeek {
/**
* Default { link FirstOfWeek}.
+ *
+ * Default in the sense that some value must be chosen if there's no available external
+ * reference.
*/
- DEFAULT = SUNDAY;
+ DEFAULT = MONDAY;
/**
* Converts the { link FirstOfWeek} into an actual { link DayOfWeek}.
@@ -34,6 +37,10 @@ public enum FirstOfWeek {
assert_not_reached();
}
}
+
+ public string to_string() {
+ return as_day_of_week().to_string();
+ }
}
}
diff --git a/src/calendar/calendar-system.vala b/src/calendar/calendar-system.vala
index fce063a..b97545a 100644
--- a/src/calendar/calendar-system.vala
+++ b/src/calendar/calendar-system.vala
@@ -16,6 +16,8 @@ namespace California.Calendar {
*/
public class System : BaseObject {
+ public const string PROP_SYSTEM_FIRST_OF_WEEK = "system-first-of-week";
+
private const string CLOCK_FORMAT_SCHEMA = "org.gnome.desktop.interface";
private const string CLOCK_FORMAT_KEY = "clock-format";
private const string CLOCK_FORMAT_24H = "24h";
@@ -64,12 +66,18 @@ public class System : BaseObject {
* 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 stored 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.
+ * the system), this is a combination of a user preference (configured by the outer application)
+ * and a system/locale setting. It's stored here because it's something that many components
+ * in { link Calendar} need access to and passing it around throughout the stack is
+ * 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.
+ *
+ * When { link Calendar.System} is first created, it's initialized to
+ * { link system_first_of_week}. The outer application may pull an overriding value from the
+ * configuration and override the original value. (The outer application may want to have some
+ * way to store "use system default" as a possible value.)
*
* @see first_of_week_changed
*/
@@ -90,6 +98,13 @@ public class System : BaseObject {
}
}
+ /**
+ * System-defined (or locale-defined) start of the week.
+ *
+ * @see first_of_week
+ */
+ public FirstOfWeek system_first_of_week { get; private set; }
+
private static DBus.timedated timedated_service;
private static DBus.Properties timedated_properties;
@@ -155,6 +170,57 @@ public class System : BaseObject {
today = new Date.now(Timezone.local);
scheduled_date_timer = new Scheduled.once_after_sec(next_check_today_interval_sec(),
check_today_changed, CHECK_DATE_PRIORITY);
+
+ // Borrowed liberally (but not exactly) from GtkCalendar; see gtk_calendar_init
+#if HAVE__NL_TIME_FIRST_WEEKDAY
+ // 1-based day (1 == Sunday)
+ int first_weekday = Langinfo.lookup_int(Langinfo.Item.INT_TIME_FIRST_WEEKDAY);
+
+ // I haven't the foggiest what this is returning, but note that Nov 30 1997 is a Sunday and
+ // Dec 01 1997 is a Monday.
+ int week_origin = (int) Langinfo.lookup(Langinfo.Item.TIME_WEEK_1STDAY);
+
+ // values are translated into 0-based day (as per gtkcalendar.c), 0 == Sunday
+ int week_1stday;
+ switch (week_origin) {
+ case 19971130:
+ week_1stday = 0;
+ break;
+
+ case 19971201:
+ week_1stday = 1;
+ break;
+
+ default:
+ warning("Unknown value of _NL_TIME_WEEK_1STDAY: %d (%Xh)", week_origin, week_origin);
+ week_1stday = 0;
+ break;
+ }
+
+ // this yields a 0-based value, 0 == Sunday
+ int week_start = (week_1stday + first_weekday - 1) % 7;
+
+ // convert into our first day of week value
+ switch (week_start) {
+ case 0:
+ system_first_of_week = FirstOfWeek.SUNDAY;
+ break;
+
+ case 1:
+ system_first_of_week = FirstOfWeek.MONDAY;
+ break;
+
+ default:
+ warning("Unknown week start value, using default: %d", week_start);
+ system_first_of_week = FirstOfWeek.DEFAULT;
+ break;
+ }
+#else
+ // For now, just use the default. Later, user will be able to configure this.
+ system_first_of_week = FirstOfWeek.DEFAULT;
+#endif
+
+ debug("System first day of week: %s", system_first_of_week.to_string());
}
internal static void preinit() throws IOError {
@@ -166,6 +232,10 @@ public class System : BaseObject {
internal static void init() {
instance = new System();
+
+ // initialize, application may override (can't do this in ctor due to how first_of_week
+ // setter is built)
+ first_of_week = instance.system_first_of_week;
}
internal static void terminate() {
diff --git a/vapi/langinfo.vapi b/vapi/langinfo.vapi
new file mode 100644
index 0000000..972fd5c
--- /dev/null
+++ b/vapi/langinfo.vapi
@@ -0,0 +1,100 @@
+/**
+ * nl_langinfo bindings.
+ */
+
+[CCode (cprefix = "")]
+namespace Langinfo {
+
+[CCode (cheader_filename = "langinfo.h", cname = "nl_langinfo")]
+public unowned string lookup(Langinfo.Item item);
+
+/**
+ * Use for { link Langinfo.Item}s prefixed with INT_.
+ */
+public int lookup_int(Langinfo.Item item) {
+ char *ptr = (char *) lookup(item);
+
+ return (ptr != null) ? *ptr : 0;
+}
+
+[CCode (cheader_filename = "langinfo.h", cname = "nl_item", cprefix = "", has_type_id = false)]
+public enum Item {
+ /* Abbreviated days of the week. */
+ ABDAY_1, /* Sunday */
+ ABDAY_2,
+ ABDAY_3,
+ ABDAY_4,
+ ABDAY_5,
+ ABDAY_6,
+ ABDAY_7,
+
+ /* Long-named (unabbreviated) days of the week. */
+ DAY_1, /* Sunday */
+ DAY_2, /* Monday */
+ DAY_3, /* Tuesday */
+ DAY_4, /* Wednesday */
+ DAY_5, /* Thursday */
+ DAY_6, /* Friday */
+ DAY_7, /* Saturday */
+
+ /* Abbreviated month names. */
+ ABMON_1, /* Jan */
+ ABMON_2,
+ ABMON_3,
+ ABMON_4,
+ ABMON_5,
+ ABMON_6,
+ ABMON_7,
+ ABMON_8,
+ ABMON_9,
+ ABMON_10,
+ ABMON_11,
+ ABMON_12,
+
+ /* Long (unabbreviated) month names. */
+ MON_1, /* January */
+ MON_2,
+ MON_3,
+ MON_4,
+ MON_5,
+ MON_6,
+ MON_7,
+ MON_8,
+ MON_9,
+ MON_10,
+ MON_11,
+ MON_12,
+
+ AM_STR, /* Ante meridiem string. (may be empty) */
+ PM_STR, /* Post meridiem string. (may be empty) */
+
+ ERA,
+
+ /**
+ * The following are not official and therefore not portable.
+ * Those prefixed with INT_ should use lookup_int() rather than lookup().
+ */
+
+ [CCode (cname = "_NL_TIME_WEEK_NDAYS")]
+ INT_TIME_WEEK_NDAYS,
+ /**
+ * TIME_WEEK_1STDAY returns a straight machine word as a constant indicating a first day (not a
+ * pointer) that is interpreted as follows:
+ * 19971130 == Sunday
+ * 19971201 == Monday
+ */
+ [CCode (cname = "_NL_TIME_WEEK_1STDAY")]
+ TIME_WEEK_1STDAY,
+ [CCode (cname = "_NL_TIME_WEEK_1STWEEK")]
+ INT_TIME_WEEK_1STWEEK,
+ [CCode (cname = "_NL_TIME_FIRST_WEEKDAY")]
+ INT_TIME_FIRST_WEEKDAY,
+ [CCode (cname = "_NL_TIME_FIRST_WORKDAY")]
+ INT_TIME_FIRST_WORKDAY,
+ [CCode (cname = "_NL_TIME_CAL_DIRECTION")]
+ INT_TIME_CAL_DIRECTION,
+ [CCode (cname = "_NL_TIME_TIMEZONE")]
+ TIME_TIMEZONE
+}
+
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]