[california/wip/725785-create-recurring: 11/11] Further cleanup of parser, handle yearly events
- From: Jim Nelson <jnelson src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [california/wip/725785-create-recurring: 11/11] Further cleanup of parser, handle yearly events
- Date: Fri, 13 Jun 2014 23:21:11 +0000 (UTC)
commit 6551c8705983fbe6a22c57d52327b91d88f2855b
Author: Jim Nelson <jim yorba org>
Date: Fri Jun 13 16:20:33 2014 -0700
Further cleanup of parser, handle yearly events
src/calendar/calendar-date.vala | 40 ++++++++++++--
src/component/component-details-parser.vala | 78 +++++++++++++++++++-------
src/component/component-recurrence-rule.vala | 34 ++++++------
src/component/component.vala | 4 +-
4 files changed, 111 insertions(+), 45 deletions(-)
---
diff --git a/src/calendar/calendar-date.vala b/src/calendar/calendar-date.vala
index ce762f0..f01ccdc 100644
--- a/src/calendar/calendar-date.vala
+++ b/src/calendar/calendar-date.vala
@@ -68,6 +68,7 @@ public class Date : Unit<Date>, Gee.Comparable<Date>, Gee.Hashable<Date> {
public DayOfWeek day_of_week { get; private set; }
public DayOfMonth day_of_month { get; private set; }
+ public int day_of_year { get; private set; }
public Month month { get; private set; }
public Year year { get; private set; }
@@ -89,6 +90,7 @@ public class Date : Unit<Date>, Gee.Comparable<Date>, Gee.Hashable<Date> {
day_of_week = DayOfWeek.from_gdate(gdate);
this.day_of_month = day_of_month;
+ day_of_year = (int) gdate.get_day_of_year();
this.month = month;
this.year = year;
}
@@ -108,6 +110,7 @@ public class Date : Unit<Date>, Gee.Comparable<Date>, Gee.Hashable<Date> {
assert(gdate.valid());
day_of_week = DayOfWeek.from_gdate(gdate);
+ day_of_year = (int) gdate.get_day_of_year();
}
/**
@@ -126,6 +129,7 @@ public class Date : Unit<Date>, Gee.Comparable<Date>, Gee.Hashable<Date> {
day_of_week = DayOfWeek.from_gdate(gdate);
day_of_month = DayOfMonth.from_gdate(gdate);
+ day_of_year = (int) gdate.get_day_of_year();
month = Month.from_gdate(gdate);
year = new Year.from_gdate(gdate);
}
@@ -256,7 +260,20 @@ public class Date : Unit<Date>, Gee.Comparable<Date>, Gee.Hashable<Date> {
* @see prior
*/
public Date upcoming(DayOfWeek dow, bool includes_this_day) {
- return upcoming_prior(dow, includes_this_day, 1);
+ return upcoming_prior(iterate<DayOfWeek>(dow).to_hash_set(), includes_this_day, 1);
+ }
+
+ /**
+ * Returns the { link Date} of the upcoming (next chronological) { link DayOfWeek} from the
+ * set provided.
+ *
+ * Set { link includes_this_day} to true if this Date is to be considered "upcoming", that is,
+ * if it falls on the day of the week, it is returned.
+ *
+ * @see prior_in_set
+ */
+ public Date upcoming_in_set(Gee.Set<DayOfWeek> dow_set, bool includes_this_day) {
+ return upcoming_prior(dow_set, includes_this_day, 1);
}
/**
@@ -268,19 +285,32 @@ public class Date : Unit<Date>, Gee.Comparable<Date>, Gee.Hashable<Date> {
* @see upcoming
*/
public Date prior(DayOfWeek dow, bool includes_this_day) {
- return upcoming_prior(dow, includes_this_day, -1);
+ return upcoming_prior(iterate<DayOfWeek>(dow).to_hash_set(), includes_this_day, -1);
+ }
+
+ /**
+ * Returns the { link Date} of the prior (next chronological) { link DayOfWeek} from the
+ * set provided.
+ *
+ * Set { link includes_this_day} to true if this Date is to be considered "prior", that is,
+ * if it falls on the day of the week, it is returned.
+ *
+ * @see upcoming_in_set
+ */
+ public Date prior_in_set(Gee.Set<DayOfWeek> dow_set, bool includes_this_day) {
+ return upcoming_prior(dow_set, includes_this_day, -1);
}
- private Date upcoming_prior(DayOfWeek dow, bool includes_this_day, int adjustment) {
+ private Date upcoming_prior(Gee.Set<DayOfWeek> dow_set, bool includes_this_day, int adjustment) {
// look for current date being the one
- if (day_of_week.equal_to(dow) && includes_this_day)
+ if (dow_set.contains(day_of_week) && includes_this_day)
return this;
// find a Date for day of the week ... brute force isn't great, but it works
Date upcoming_prior = this;
for (;;) {
upcoming_prior = upcoming_prior.adjust(adjustment);
- if (upcoming_prior.day_of_week.equal_to(dow))
+ if (dow_set.contains(upcoming_prior.day_of_week))
return upcoming_prior;
}
}
diff --git a/src/component/component-details-parser.vala b/src/component/component-details-parser.vala
index a013892..ffeabda 100644
--- a/src/component/component-details-parser.vala
+++ b/src/component/component-details-parser.vala
@@ -351,57 +351,93 @@ public class DetailsParser : BaseObject {
return true;
}
- private bool parse_recurring(Token? unit) {
- // if a recurring rule has already been specified, another recurring cannot be made
- if (unit == null || rrule != null)
+ private bool parse_recurring(Token? specifier) {
+ // if a recurring rule has already been specified, another recurring cannot be made and
+ // the current cannot be edited (yet)
+ if (specifier == null || rrule != null)
return false;
// a day of the week
- Calendar.DayOfWeek? dow = Calendar.DayOfWeek.parse(unit.casefolded);
+ Calendar.DayOfWeek? dow = Calendar.DayOfWeek.parse(specifier.casefolded);
if (dow != null) {
start_date = Calendar.System.today.upcoming(dow, true);
rrule = new RecurrenceRule(iCal.icalrecurrencetype_frequency.WEEKLY_RECURRENCE);
+ rrule.first_of_week = Calendar.System.first_of_week.as_day_of_week();
return true;
}
// "day"
- if (unit.casefolded == DAY) {
+ if (specifier.casefolded == DAY) {
start_date = Calendar.System.today;
rrule = new RecurrenceRule(iCal.icalrecurrencetype_frequency.DAILY_RECURRENCE);
+ rrule.first_of_week = Calendar.System.first_of_week.as_day_of_week();
return true;
}
// "weekday"
- if (unit.casefolded == WEEKDAY) {
- start_date = Calendar.System.today;
- rrule = new RecurrenceRule(iCal.icalrecurrencetype_frequency.WEEKLY_RECURRENCE);
- // TODO: Set start of week
- Gee.Map<Calendar.DayOfWeek, int> map = new Gee.HashMap<Calendar.DayOfWeek, int>();
- foreach (Calendar.DayOfWeek weekday in Calendar.DayOfWeek.weekdays)
- map.set(weekday, 0);
- rrule.set_by_rule(RecurrenceRule.ByRule.DAY, RecurrenceRule.encode_days(map));
+ if (specifier.casefolded == WEEKDAY) {
+ set_rrule_weekly(Calendar.DayOfWeek.weekdays);
return true;
}
// "weekend"
- if (unit.casefolded == WEEKEND) {
- start_date = Calendar.System.today;
- rrule = new RecurrenceRule(iCal.icalrecurrencetype_frequency.WEEKLY_RECURRENCE);
- // TODO: Set start of week
- Gee.Map<Calendar.DayOfWeek, int> map = new Gee.HashMap<Calendar.DayOfWeek, int>();
- foreach (Calendar.DayOfWeek weekend_day in Calendar.DayOfWeek.weekend_days)
- map.set(weekend_day, 0);
- rrule.set_by_rule(RecurrenceRule.ByRule.DAY, RecurrenceRule.encode_days(map));
+ if (specifier.casefolded == WEEKEND) {
+ set_rrule_weekly(Calendar.DayOfWeek.weekend_days);
return true;
}
+ // if no start date, then parse for start date, and if so, treat as yearly event
+ if (start_date == null) {
+ stack.mark();
+ {
+ Token? second = stack.pop();
+ if (second != null) {
+ Calendar.Date? date = parse_day_month(specifier, second);
+ if (date == null)
+ date = parse_day_month(second, specifier);
+
+ if (date != null) {
+ set_rrule_yearly(date);
+
+ return true;
+ }
+ }
+ }
+ stack.restore();
+ }
+
return false;
}
+ private void set_rrule_weekly(Calendar.DayOfWeek[]? by_days) {
+ Gee.Map<Calendar.DayOfWeek, int> map = new Gee.HashMap<Calendar.DayOfWeek, int>();
+ if (by_days != null) {
+ foreach (Calendar.DayOfWeek by_day in by_days)
+ map.set(by_day, 0);
+ }
+
+ // start at the first day in the by_days
+ start_date = Calendar.System.today;
+ if (by_days != null)
+ start_date = start_date.upcoming_in_set(from_array<Calendar.DayOfWeek>(by_days).to_hash_set(),
true);
+
+ rrule = new RecurrenceRule(iCal.icalrecurrencetype_frequency.WEEKLY_RECURRENCE);
+ rrule.first_of_week = Calendar.System.first_of_week.as_day_of_week();
+ rrule.set_by_rule(RecurrenceRule.ByRule.DAY, RecurrenceRule.encode_days(map));
+ }
+
+ private void set_rrule_yearly(Calendar.Date date) {
+ start_date = date;
+
+ rrule = new RecurrenceRule(iCal.icalrecurrencetype_frequency.YEARLY_RECURRENCE);
+ rrule.first_of_week = Calendar.System.first_of_week.as_day_of_week();
+ rrule.set_by_rule(RecurrenceRule.ByRule.YEAR_DAY, iterate<int>(date.day_of_year).to_array_list());
+ }
+
// Adds the text to the summary and location field, if adding_location is set
private void add_text(Token token) {
// always add to summary
diff --git a/src/component/component-recurrence-rule.vala b/src/component/component-recurrence-rule.vala
index 4648ee9..12dd603 100644
--- a/src/component/component-recurrence-rule.vala
+++ b/src/component/component-recurrence-rule.vala
@@ -72,7 +72,7 @@ public class RecurrenceRule : BaseObject {
/**
* Start of work week (WKST).
*/
- public Calendar.DayOfWeek? start_of_week { get; set; default = null; }
+ public Calendar.DayOfWeek? first_of_week { get; set; default = null; }
private Gee.SortedSet<int> by_second = new Gee.TreeSet<int>();
private Gee.SortedSet<int> by_minute = new Gee.TreeSet<int>();
@@ -114,36 +114,36 @@ public class RecurrenceRule : BaseObject {
switch (rrule.week_start) {
case iCal.icalrecurrencetype_weekday.SUNDAY_WEEKDAY:
- start_of_week = Calendar.DayOfWeek.SUN;
+ first_of_week = Calendar.DayOfWeek.SUN;
break;
case iCal.icalrecurrencetype_weekday.MONDAY_WEEKDAY:
- start_of_week = Calendar.DayOfWeek.MON;
+ first_of_week = Calendar.DayOfWeek.MON;
break;
case iCal.icalrecurrencetype_weekday.TUESDAY_WEEKDAY:
- start_of_week = Calendar.DayOfWeek.TUE;
+ first_of_week = Calendar.DayOfWeek.TUE;
break;
case iCal.icalrecurrencetype_weekday.WEDNESDAY_WEEKDAY:
- start_of_week = Calendar.DayOfWeek.WED;
+ first_of_week = Calendar.DayOfWeek.WED;
break;
case iCal.icalrecurrencetype_weekday.THURSDAY_WEEKDAY:
- start_of_week = Calendar.DayOfWeek.THU;
+ first_of_week = Calendar.DayOfWeek.THU;
break;
case iCal.icalrecurrencetype_weekday.FRIDAY_WEEKDAY:
- start_of_week = Calendar.DayOfWeek.FRI;
+ first_of_week = Calendar.DayOfWeek.FRI;
break;
case iCal.icalrecurrencetype_weekday.SATURDAY_WEEKDAY:
- start_of_week = Calendar.DayOfWeek.SAT;
+ first_of_week = Calendar.DayOfWeek.SAT;
break;
case iCal.icalrecurrencetype_weekday.NO_WEEKDAY:
default:
- start_of_week = null;
+ first_of_week = null;
break;
}
@@ -331,21 +331,21 @@ public class RecurrenceRule : BaseObject {
if (interval > 0)
rrule.interval = interval;
- if (start_of_week == null)
+ if (first_of_week == null)
rrule.week_start = iCal.icalrecurrencetype_weekday.NO_WEEKDAY;
- else if (start_of_week == Calendar.DayOfWeek.SUN)
+ else if (first_of_week == Calendar.DayOfWeek.SUN)
rrule.week_start = iCal.icalrecurrencetype_weekday.SUNDAY_WEEKDAY;
- else if (start_of_week == Calendar.DayOfWeek.MON)
+ else if (first_of_week == Calendar.DayOfWeek.MON)
rrule.week_start = iCal.icalrecurrencetype_weekday.MONDAY_WEEKDAY;
- else if (start_of_week == Calendar.DayOfWeek.TUE)
+ else if (first_of_week == Calendar.DayOfWeek.TUE)
rrule.week_start = iCal.icalrecurrencetype_weekday.TUESDAY_WEEKDAY;
- else if (start_of_week == Calendar.DayOfWeek.WED)
+ else if (first_of_week == Calendar.DayOfWeek.WED)
rrule.week_start = iCal.icalrecurrencetype_weekday.WEDNESDAY_WEEKDAY;
- else if (start_of_week == Calendar.DayOfWeek.THU)
+ else if (first_of_week == Calendar.DayOfWeek.THU)
rrule.week_start = iCal.icalrecurrencetype_weekday.THURSDAY_WEEKDAY;
- else if (start_of_week == Calendar.DayOfWeek.FRI)
+ else if (first_of_week == Calendar.DayOfWeek.FRI)
rrule.week_start = iCal.icalrecurrencetype_weekday.FRIDAY_WEEKDAY;
- else if (start_of_week == Calendar.DayOfWeek.SAT)
+ else if (first_of_week == Calendar.DayOfWeek.SAT)
rrule.week_start = iCal.icalrecurrencetype_weekday.SATURDAY_WEEKDAY;
else
assert_not_reached();
diff --git a/src/component/component.vala b/src/component/component.vala
index 82b9975..c7be790 100644
--- a/src/component/component.vala
+++ b/src/component/component.vala
@@ -69,9 +69,9 @@ public void init() throws Error {
// It's allowable for some or all of these words to
// be duplicated in the location prepositions list (elsewhere) but not another time list.
// The list can be empty, but that will limit the parser.
- // Examples: "at 9am", "from 10pm to 11:30pm", "on monday"
+ // Examples: "at 9am", "from 10pm to 11:30pm", "on monday", "until June 3rd"
// For more information see https://wiki.gnome.org/Apps/California/TranslatingQuickAdd
- TIME_PREPOSITIONS = _("at;from;to;on;").casefold().split(";");
+ TIME_PREPOSITIONS = _("at;from;to;on;until;").casefold().split(";");
// Used by quick-add to determine if the word is a DURATION preposition (indicating a
// a duration of time, not a specific time). Each word must be separated by semi-colons.
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]