[california] Specify location and time w/ at-sign in Quick Add: Bug #732033
- From: Jim Nelson <jnelson src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [california] Specify location and time w/ at-sign in Quick Add: Bug #732033
- Date: Fri, 15 Aug 2014 18:48:25 +0000 (UTC)
commit d35ba37e3f48521b147c3d39dc38088c26b125e0
Author: Jim Nelson <jim yorba org>
Date: Fri Aug 15 11:47:25 2014 -0700
Specify location and time w/ at-sign in Quick Add: Bug #732033
In addition, if the at-sign is used for location, the location won't
be added to the summary.
src/component/component-details-parser.vala | 80 +++++++++++++++++++++++----
src/tests/tests-quick-add.vala | 34 +++++++++++
2 files changed, 103 insertions(+), 11 deletions(-)
---
diff --git a/src/component/component-details-parser.vala b/src/component/component-details-parser.vala
index 3f6b854..10b42e1 100644
--- a/src/component/component-details-parser.vala
+++ b/src/component/component-details-parser.vala
@@ -19,13 +19,56 @@ namespace California.Component {
*/
public class DetailsParser : BaseObject {
+ /**
+ * Recognized "special" symbols.
+ */
+ private enum Shorthand {
+ NONE,
+ /**
+ * { link Shorthand} for TIME or LOCATION.
+ */
+ ATSIGN;
+
+ /**
+ * Converts a string to a recognized { link Shorthand}.
+ */
+ public static Shorthand parse(string str) {
+ switch (str) {
+ case "@":
+ return ATSIGN;
+
+ default:
+ return NONE;
+ }
+ }
+ }
+
private class Token : BaseObject, Gee.Hashable<Token> {
+ /**
+ * Original token.
+ */
public string original;
+
+ /*
+ * Casefolded and punctuation removed.
+ */
public string casefolded;
+ /**
+ * { link Shorthand} parsed from { link original}.
+ */
+ public Shorthand shorthand;
+
public Token(string token) {
original = token;
- casefolded = from_string(token.casefold()).filter(c => !c.ispunct()).to_string(c =>
c.to_string()) ?? "";
+ casefolded = from_string(token.casefold())
+ .filter(c => !c.ispunct())
+ .to_string(c => c.to_string()) ?? "";
+ shorthand = Shorthand.parse(original);
+ }
+
+ public bool is_empty() {
+ return String.is_empty(casefolded) && shorthand == Shorthand.NONE;
}
public bool equal_to(Token other) {
@@ -64,6 +107,7 @@ public class DetailsParser : BaseObject {
private Calendar.Date? end_date = null;
private Calendar.Duration? duration = null;
private bool adding_location = false;
+ private bool adding_summary = true;
private RecurrenceRule? rrule = null;
/**
@@ -131,8 +175,8 @@ public class DetailsParser : BaseObject {
break;
// because whitespace and punctuation is stripped from the original token, it's possible
- // for the casefolded token to be empty
- if (String.is_empty(token.casefolded)) {
+ // for the casefolded token to be empty (and an unrecognized Shorthand)
+ if (token.is_empty()) {
add_text(token);
continue;
@@ -155,6 +199,12 @@ public class DetailsParser : BaseObject {
continue;
stack.restore();
+ // The ATSIGN is also recognized as a TIME preposition
+ stack.mark();
+ if (token.shorthand == Shorthand.ATSIGN && parse_time(stack.pop(), false))
+ continue;
+ stack.restore();
+
// A duration preposition suggests a specific amount of positive time is being described
// by the next two tokens.
stack.mark();
@@ -176,16 +226,25 @@ public class DetailsParser : BaseObject {
continue;
stack.restore();
- // only look for location prepositions if not already adding text to the location field
- if (!adding_location && token.casefolded in LOCATION_PREPOSITIONS) {
+ // only look for LOCATION prepositions if not already adding text to the location field
+ // (ATSIGN is considered a LOCATION preposition)
+ if (!adding_location
+ && (token.casefolded in LOCATION_PREPOSITIONS || token.shorthand == Shorthand.ATSIGN)) {
// add current token (the preposition) to summary but not location (because location
// tokens are added to summary, i.e. "dinner at John's" yields "John's" for location
- // and "dinner at John's" for summary)
- add_text(token);
+ // and "dinner at John's" for summary) ... note that ATSIGN does not add to summary
+ // to allow for more concise summaries
+ if (token.shorthand != Shorthand.ATSIGN)
+ add_text(token);
// now adding to both summary and location
adding_location = true;
+ // ...unless at-sign used, which has the side-effect of not adding to summary
+ // (see above)
+ if (token.shorthand == Shorthand.ATSIGN)
+ adding_summary = false;
+
continue;
}
@@ -727,12 +786,11 @@ public class DetailsParser : BaseObject {
return true;
}
- // Adds the text to the summary and location field, if adding_location is set
+ // Adds the text to the summary and location field, if adding_location/summary is set
private void add_text(Token token) {
- // always add to summary
- add_to_builder(summary, token);
+ if (adding_summary)
+ add_to_builder(summary, token);
- // add to location if in that mode
if (adding_location)
add_to_builder(location, token);
}
diff --git a/src/tests/tests-quick-add.vala b/src/tests/tests-quick-add.vala
index c902c37..371cd66 100644
--- a/src/tests/tests-quick-add.vala
+++ b/src/tests/tests-quick-add.vala
@@ -53,6 +53,8 @@ private class QuickAdd : UnitTest.Harness {
add_case("time-range-one-meridiem", time_range_one_meridiem);
add_case("time-range-24hr", time_range_24hr);
add_case("time-range-no-meridiem", time_range_no_meridiem);
+ add_case("atsign-location", atsign_location);
+ add_case("atsign-time", atsign_time);
}
protected override void setup() throws Error {
@@ -598,6 +600,38 @@ private class QuickAdd : UnitTest.Harness {
return parser.event.summary == "6-9 Opus Affair"
&& !parser.event.is_valid(false);
}
+
+ private bool atsign_location(out string? dump) throws Error {
+ Component.DetailsParser parser = new Component.DetailsParser(
+ "Dinner @ Tadich Grill 7pm", null);
+
+ dump = parser.event.source;
+
+ return parser.event.summary == "Dinner"
+ && parser.event.location == "Tadich Grill"
+ && !parser.event.is_all_day
+ && parser.event.exact_time_span.start_exact_time.hour == 19
+ && parser.event.exact_time_span.start_exact_time.minute == 0
+ && parser.event.exact_time_span.end_exact_time.hour == 20
+ && parser.event.exact_time_span.end_exact_time.minute == 0
+ && parser.event.exact_time_span.get_date_span().equal_to(Calendar.System.today.to_date_span());
+ }
+
+ private bool atsign_time(out string? dump) throws Error {
+ Component.DetailsParser parser = new Component.DetailsParser(
+ "Dinner @ 7pm", null);
+
+ dump = parser.event.source;
+
+ return parser.event.summary == "Dinner"
+ && parser.event.location == null
+ && !parser.event.is_all_day
+ && parser.event.exact_time_span.start_exact_time.hour == 19
+ && parser.event.exact_time_span.start_exact_time.minute == 0
+ && parser.event.exact_time_span.end_exact_time.hour == 20
+ && parser.event.exact_time_span.end_exact_time.minute == 0
+ && parser.event.exact_time_span.get_date_span().equal_to(Calendar.System.today.to_date_span());
+ }
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]