[california/wip/732930-explain] All potential text in place, now add to UI
- From: Jim Nelson <jnelson src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [california/wip/732930-explain] All potential text in place, now add to UI
- Date: Fri, 5 Sep 2014 21:50:18 +0000 (UTC)
commit eec72be48929d3716cda6b79d984464c1653643d
Author: Jim Nelson <jim yorba org>
Date: Fri Sep 5 12:38:42 2014 -0700
All potential text in place, now add to UI
src/calendar/calendar-day-of-week.vala | 21 ++++
src/component/component-recurrence-rule.vala | 160 ++++++++++++++++++++++----
src/host/host-create-update-recurring.vala | 8 +-
3 files changed, 166 insertions(+), 23 deletions(-)
---
diff --git a/src/calendar/calendar-day-of-week.vala b/src/calendar/calendar-day-of-week.vala
index 4fc8500..0ace8c3 100644
--- a/src/calendar/calendar-day-of-week.vala
+++ b/src/calendar/calendar-day-of-week.vala
@@ -277,6 +277,27 @@ public class DayOfWeek : BaseObject, Gee.Hashable<DayOfWeek> {
return new DayOfWeekIterator(first_of_week);
}
+ public static CompareDataFunc<DayOfWeek> get_comparator_for_first_of_week(FirstOfWeek fow) {
+ switch (fow) {
+ case FirstOfWeek.MONDAY:
+ return monday_comparator;
+
+ case FirstOfWeek.SUNDAY:
+ return sunday_comparator;
+
+ default:
+ assert_not_reached();
+ }
+ }
+
+ private static int monday_comparator(DayOfWeek a, DayOfWeek b) {
+ return a.value_monday - b.value_monday;
+ }
+
+ private static int sunday_comparator(DayOfWeek a, DayOfWeek b) {
+ return a.value_sunday - b.value_sunday;
+ }
+
public bool equal_to(DayOfWeek other) {
return this == other;
}
diff --git a/src/component/component-recurrence-rule.vala b/src/component/component-recurrence-rule.vala
index 16774cb..8a72ce2 100644
--- a/src/component/component-recurrence-rule.vala
+++ b/src/component/component-recurrence-rule.vala
@@ -354,9 +354,7 @@ public class RecurrenceRule : BaseObject {
* Encode a Gee.Map of { link Calendar.DayOfWeek} and its position into a value for
* { link set_by_rule} when using { link ByRule.DAY}.
*
- * Use null for DayOfWeek and zero for position to mean "any" or "every".
- *
- * @see encode_day
+ * See { link encode_day} for more information about how encoding works.
*/
public static Gee.Collection<int> encode_days(Gee.Map<Calendar.DayOfWeek?, int>? day_values) {
if (day_values == null || day_values.size == 0)
@@ -432,6 +430,9 @@ public class RecurrenceRule : BaseObject {
/**
* Returns a read-only sorted set of BY rule settings for the specified { link ByRule}.
*
+ * Note that because BYDAY rules are bit-encoded, their sorting has no relationship to their
+ * decoded values. Callers should decode each value and sort them according to their needs.
+ *
* See [[https://tools.ietf.org/html/rfc5545#section-3.3.10]] for information how these values
* operate according to their associated ByRule and this RRULE's { link freq}.
*/
@@ -615,11 +616,11 @@ public class RecurrenceRule : BaseObject {
}
- private string explain_simple(string unit) {
+ private string explain_simple(string units) {
if (count > 0) {
// As in, "Repeats every day, 2 times"
return _("Repeats every %s, %s").printf(units,
- ngettext("%d time", "%d times").printf(count)
+ ngettext("%d time", "%d times", count).printf(count)
);
}
@@ -642,15 +643,11 @@ public class RecurrenceRule : BaseObject {
return _("Repeats every %s").printf(units);
}
- private string? explain_weekly(string unit) {
- // can only explain BYDAY rules
- Gee.Set<ByRule> active = get_active_by_rules();
- if (!active.contains(ByRule.DAY) || active.size == 0)
- return null;
-
- // Gather all the DayOfWeeks in the WEEKLY RRULE into a sorted set
- // TODO: Need start-of-week comparator
- Gee.TreeSet<Calendar.DayOfWeek> dows = new Gee.TreeSet<Calendar.DayOfWeek>();
+ // Use only with WEEKLY RRULEs
+ private string? explain_days_of_the_week() {
+ // Gather all the DayOfWeeks amd sort by start of week
+ Gee.TreeSet<Calendar.DayOfWeek> dows = new Gee.TreeSet<Calendar.DayOfWeek>(
+ Calendar.DayOfWeek.get_comparator_for_first_of_week(Calendar.System.first_of_week));
foreach (int day in get_by_rule(ByRule.DAY)) {
Calendar.DayOfWeek dow;
if (!decode_day(day, out dow, null))
@@ -663,7 +660,7 @@ public class RecurrenceRule : BaseObject {
if (dows.size == 0)
return null;
- // assemble a list of days
+ // assemble a text list of days
StringBuilder days_of_the_week = new StringBuilder();
bool first = true;
foreach (Calendar.DayOfWeek dow in dows) {
@@ -676,36 +673,155 @@ public class RecurrenceRule : BaseObject {
first = false;
}
+ return days_of_the_week.str;
+ }
+
+ private string? explain_weekly(string units) {
+ // can only explain BYDAY rules
+ Gee.Set<ByRule> active = get_active_by_rules();
+ if (!active.contains(ByRule.DAY) || active.size == 0)
+ return null;
+
+ string? days_of_the_week = explain_days_of_the_week();
+ if (String.is_empty(days_of_the_week))
+ return null;
+
if (count > 0) {
// As in, "Repeats every week on Monday, Tuesday, 3 times"
- return _("Repeats every %s on %s, %s").printf(units, days_of_the_week.str,
- ngettext("%d time", "%d times").printf(count)
+ return _("Repeats every %s on %s, %s").printf(units, days_of_the_week,
+ ngettext("%d time", "%d times", count).printf(count)
);
}
if (until_date != null) {
// As in, "Repeats every week on Thursday until Sept. 2, 2014"
- return _("Repeats every %s on %s until %s").printf(units, days_of_the_week.str,
+ return _("Repeats every %s on %s until %s").printf(units, days_of_the_week,
until_date.to_pretty_string(Calendar.Date.PrettyFlag.INCLUDE_YEAR)
);
}
if (until_exact_time != null) {
// As in, "Repeats every week on Friday, Saturday until Sept. 2, 2014, 8:00pm"
- return _("Repeats every %s on %s until %s, %s").printf(units, days_of_the_week.str,
+ return _("Repeats every %s on %s until %s, %s").printf(units, days_of_the_week,
until_exact_time.to_pretty_date_string(Calendar.Date.PrettyFlag.INCLUDE_YEAR),
until_exact_time.to_pretty_time_string(Calendar.WallTime.PrettyFlag.NONE)
);
}
// As in, "Repeats every week on Monday, Wednesday, Friday"
- return _("Repeats every %s on %s").printf(units, days_of_the_week.str);
+ return _("Repeats every %s on %s").printf(units, days_of_the_week);
}
- private string? explain_monthly_byday(string unit) {
+ private string? explain_monthly_byday(string units) {
+ // only support one day of the week for BYMONTHDAT RRULEs
+ Gee.Set<int> byday = get_by_rule(ByRule.DAY);
+ if (byday.size != 1)
+ return null;
+
+ Calendar.DayOfWeek? dow;
+ int position;
+ if (!decode_day(traverse<int>(byday).first(), out dow, out position))
+ return null;
+
+ // only support a small set of possibilites here
+ if (dow == null)
+ return null;
+
+ string day;
+ switch (position) {
+ case 1:
+ // As in, "first Thursday of the month"
+ day = _("first %s").printf(dow.full_name);
+ break;
+
+ case 2:
+ // As in, "second Thursday of the month"
+ day = _("second %s").printf(dow.full_name);
+ break;
+
+ case 3:
+ // As in, "third Thursday of the month"
+ day = _("third %s").printf(dow.full_name);
+ break;
+
+ case 4:
+ // As in, "fourth Thursday of the month"
+ day = _("fourth %s").printf(dow.full_name);
+ break;
+
+ case 5:
+ // As in, "fifth Thursday of the month"
+ day = _("fifth %s").printf(dow.full_name);
+ break;
+
+ case -1:
+ // As in, "last Thursday of the month"
+ day = _("last %s").printf(dow.full_name);
+ break;
+
+ default:
+ return null;
+ }
+
+ if (count > 0) {
+ // As in, "Repeats every month on the first Tuesday, 3 times"
+ return _("Repeats every %s on the %s, %s").printf(units, day,
+ ngettext("%d time", "%d times", count).printf(count)
+ );
+ }
+
+ if (until_date != null) {
+ // As in, "Repeats every month on the second Monday until Sept. 2, 2014"
+ return _("Repeats every %s on the %s until %s").printf(units, day,
+ until_date.to_pretty_string(Calendar.Date.PrettyFlag.INCLUDE_YEAR)
+ );
+ }
+
+ if (until_exact_time != null) {
+ // As in, "Repeats every month on the last Friday until Sept. 2, 2014, 8:00pm"
+ return _("Repeats every %s on the %s until %s, %s").printf(units, day,
+ until_exact_time.to_pretty_date_string(Calendar.Date.PrettyFlag.INCLUDE_YEAR),
+ until_exact_time.to_pretty_time_string(Calendar.WallTime.PrettyFlag.NONE)
+ );
+ }
+
+ // As in, "Repeats every month on the third Tuesday"
+ return _("Repeats every %s on the %s").printf(units, day);
}
- private string? explain_monthly_bymonthday(string unit) {
+ private string? explain_monthly_bymonthday(string units) {
+ // currently only support one monthday (generally, the same as DTSTART)
+ Gee.Set<int> monthdays = get_by_rule(ByRule.MONTH_DAY);
+ if (monthdays.size != 1)
+ return null;
+
+ // As in, "Repeats on day 4 of the month"
+ string day = "day %d".printf(traverse<int>(monthdays).first());
+
+ if (count > 0) {
+ // As in, "Repeats every month on day 4, 3 times"
+ return _("Repeats every %s on %s, %s").printf(units, day,
+ ngettext("%d time", "%d times", count).printf(count)
+ );
+ }
+
+ if (until_date != null) {
+ // As in, "Repeats every month on day 21 until Sept. 2, 2014"
+ return _("Repeats every %s on %s until %s").printf(units, day,
+ until_date.to_pretty_string(Calendar.Date.PrettyFlag.INCLUDE_YEAR)
+ );
+ }
+
+ if (until_exact_time != null) {
+ // As in, "Repeats every month on day 20 until Sept. 2, 2014, 8:00pm"
+ return _("Repeats every %s on %s until %s, %s").printf(units, day,
+ until_exact_time.to_pretty_date_string(Calendar.Date.PrettyFlag.INCLUDE_YEAR),
+ until_exact_time.to_pretty_time_string(Calendar.WallTime.PrettyFlag.NONE)
+ );
+ }
+
+ // As in, "Repeats every month on day 5"
+ return _("Repeats every %s on %s").printf(units, day);
}
public override string to_string() {
diff --git a/src/host/host-create-update-recurring.vala b/src/host/host-create-update-recurring.vala
index 8d9fb7f..3e202ac 100644
--- a/src/host/host-create-update-recurring.vala
+++ b/src/host/host-create-update-recurring.vala
@@ -539,8 +539,14 @@ public class CreateUpdateRecurring : Gtk.Grid, Toolkit.Card {
if (rrule.is_monthly) {
if (repeats_combobox.active == Repeats.DAY_OF_THE_WEEK) {
+ // if > 4th week of month, use last week position indicator, since many months don't
+ // have more than 4 weeks
+ int position = start_date.week_of(Calendar.System.first_of_week).week_of_month;
+ if (position > 4)
+ position = -1;
+
Gee.HashMap<Calendar.DayOfWeek?, int> by_day = new Gee.HashMap<Calendar.DayOfWeek?, int>();
- by_day[start_date.day_of_week] =
start_date.week_of(Calendar.System.first_of_week).week_of_month;
+ by_day[start_date.day_of_week] = position;
rrule.set_by_rule(Component.RecurrenceRule.ByRule.DAY,
Component.RecurrenceRule.encode_days(by_day));
} else {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]