[california/wip/725783-time] Further refinements, including clamping
- From: Jim Nelson <jnelson src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [california/wip/725783-time] Further refinements, including clamping
- Date: Tue, 5 Aug 2014 00:51:29 +0000 (UTC)
commit a322d663c0e2ba8cb5aa391f28321b40d3a1714c
Author: Jim Nelson <jim yorba org>
Date: Mon Aug 4 17:24:58 2014 -0700
Further refinements, including clamping
src/Makefile.am | 1 +
src/calendar/calendar-date.vala | 2 +
src/calendar/calendar-exact-time.vala | 21 ++++++++++
src/host/host-date-time-widget.vala | 29 +++++++++++--
src/host/host-event-time-settings.vala | 42 ++++++++++++++++----
src/tests/tests-calendar-exact-time.vala | 63 ++++++++++++++++++++++++++++++
src/tests/tests.vala | 1 +
7 files changed, 146 insertions(+), 13 deletions(-)
---
diff --git a/src/Makefile.am b/src/Makefile.am
index 95d1833..a858b9a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -107,6 +107,7 @@ california_VALASOURCES = \
\
tests/tests.vala \
tests/tests-calendar-date.vala \
+ tests/tests-calendar-exact-time.vala \
tests/tests-calendar-month-of-year.vala \
tests/tests-calendar-month-span.vala \
tests/tests-calendar-wall-time.vala \
diff --git a/src/calendar/calendar-date.vala b/src/calendar/calendar-date.vala
index 9f0e71f..2f8da5c 100644
--- a/src/calendar/calendar-date.vala
+++ b/src/calendar/calendar-date.vala
@@ -296,6 +296,8 @@ public class Date : Unit<Date>, Gee.Comparable<Date>, Gee.Hashable<Date> {
/**
* Returns a { link Date} clamped between the two supplied Dates, inclusive.
+ *
+ * @see Span.clamp_between
*/
public Date clamp(Date min, Date max) {
GLib.Date clone = gdate;
diff --git a/src/calendar/calendar-exact-time.vala b/src/calendar/calendar-exact-time.vala
index 49ff335..d508dae 100644
--- a/src/calendar/calendar-exact-time.vala
+++ b/src/calendar/calendar-exact-time.vala
@@ -162,6 +162,27 @@ public class ExactTime : BaseObject, Gee.Comparable<ExactTime>, Gee.Hashable<Exa
}
/**
+ * Clamp the { link ExactTime} between a supplied floor and ceiling ExactTime.
+ *
+ * If null is passed for either value, it will be ignored (effectively making clamp() work like
+ * a floor() or ceiling() method). If null is passed for both, the current ExactTime is
+ * returned.
+ *
+ * Results are indeterminate if a floor chronologically later than a ceiling is passed in.
+ */
+ public ExactTime clamp(ExactTime? floor, ExactTime? ceiling) {
+ ExactTime clamped = this;
+
+ if (floor != null && clamped.compare_to(floor) < 0)
+ clamped = floor;
+
+ if (ceiling != null && clamped.compare_to(ceiling) > 0)
+ clamped = ceiling;
+
+ return clamped;
+ }
+
+ /**
* See DateTime.to_unix_time.
*/
public time_t to_time_t() {
diff --git a/src/host/host-date-time-widget.vala b/src/host/host-date-time-widget.vala
index b12859f..4dd0c20 100644
--- a/src/host/host-date-time-widget.vala
+++ b/src/host/host-date-time-widget.vala
@@ -12,6 +12,8 @@ public class DateTimeWidget : Gtk.Box {
public const string PROP_ENABLE_DATE = "enable-date";
public const string PROP_DATE = "date";
public const string PROP_WALL_TIME = "wall-time";
+ public const string PROP_FLOOR = "floor";
+ public const string PROP_CEILING = "ceiling";
public bool enable_time { get; set; default = true; }
@@ -21,6 +23,10 @@ public class DateTimeWidget : Gtk.Box {
public Calendar.WallTime wall_time { get; set; default = Calendar.System.now.to_wall_time(); }
+ public Calendar.ExactTime? floor { get; set; default = null; }
+
+ public Calendar.ExactTime? ceiling { get; set; default = null; }
+
[GtkChild]
private Gtk.Calendar calendar;
@@ -133,8 +139,9 @@ public class DateTimeWidget : Gtk.Box {
if (!adjust_time_controls(details, out amount, out time_unit))
return Toolkit.PROPAGATE;
+ // adjust wall time and ensure it's clamped
// this will update the entry fields, so don't disconnect widget signals
- wall_time = wall_time.adjust(amount, time_unit, null);
+ wall_time = get_clamped(date, wall_time.adjust(amount, time_unit, null)).to_wall_time();
return Toolkit.STOP;
}
@@ -147,10 +154,10 @@ public class DateTimeWidget : Gtk.Box {
amount = -1;
time_unit = Calendar.TimeUnit.HOUR;
} else if (details.widget == minutes_up) {
- amount = 1;
+ amount = 5;
time_unit = Calendar.TimeUnit.MINUTE;
} else if (details.widget == minutes_down) {
- amount = -1;
+ amount = -5;
time_unit = Calendar.TimeUnit.MINUTE;
} else if (details.widget == meridiem_up) {
amount = 12;
@@ -168,6 +175,13 @@ public class DateTimeWidget : Gtk.Box {
return true;
}
+ private Calendar.ExactTime get_clamped(Calendar.Date proposed_date, Calendar.WallTime proposed_time) {
+ Calendar.ExactTime exact_time = new Calendar.ExactTime(Calendar.Timezone.local, proposed_date,
+ proposed_time);
+
+ return exact_time.clamp(floor, ceiling);
+ }
+
private Calendar.Date? get_selected_date() {
if (calendar.day == 0)
return null;
@@ -189,8 +203,13 @@ public class DateTimeWidget : Gtk.Box {
disconnect_property_signals();
Calendar.Date? selected = get_selected_date();
- if (selected != null && !selected.equal_to(date))
- date = selected;
+ if (selected != null) {
+ // clamp selected date; if not the same as selected, select it (in effect, prevents the
+ // user from selecting a date on the GtkCalendar outside of range)
+ date = new Calendar.Date.from_exact_time(get_clamped(selected, wall_time));
+ if (!date.equal_to(selected))
+ on_date_changed();
+ }
connect_property_signals();
}
diff --git a/src/host/host-event-time-settings.vala b/src/host/host-event-time-settings.vala
index 885a7d6..5253cc6 100644
--- a/src/host/host-event-time-settings.vala
+++ b/src/host/host-event-time-settings.vala
@@ -77,10 +77,10 @@ public class EventTimeSettings : Gtk.Box, Toolkit.Card {
from_box.pack_start(from_widget);
to_box.pack_start(to_widget);
- from_widget.notify[DateTimeWidget.PROP_DATE].connect(on_update_summary);
- from_widget.notify[DateTimeWidget.PROP_WALL_TIME].connect(on_update_summary);
- to_widget.notify[DateTimeWidget.PROP_DATE].connect(on_update_summary);
- to_widget.notify[DateTimeWidget.PROP_WALL_TIME].connect(on_update_summary);
+ from_widget.notify[DateTimeWidget.PROP_DATE].connect(on_from_changed);
+ from_widget.notify[DateTimeWidget.PROP_WALL_TIME].connect(on_from_changed);
+ to_widget.notify[DateTimeWidget.PROP_DATE].connect(on_to_changed);
+ to_widget.notify[DateTimeWidget.PROP_WALL_TIME].connect(on_to_changed);
all_day_checkbutton.notify["active"].connect(on_update_summary);
all_day_checkbutton.bind_property("active", from_widget, DateTimeWidget.PROP_ENABLE_TIME,
@@ -98,18 +98,28 @@ public class EventTimeSettings : Gtk.Box, Toolkit.Card {
public void jumped_to(Toolkit.Card? from, Toolkit.Card.Jump reason, Value? message_value) {
message = (Message) message_value;
+ Calendar.DateSpan date_span = message.get_event_date_span(Calendar.Timezone.local);
+ from_widget.date = date_span.start_date;
+ to_widget.date = date_span.end_date;
+
// only set wall time if not all day; let old wall times float so user can return to them
// later while Deck is active
if (message.exact_time_span != null) {
Calendar.ExactTimeSpan time_span = message.exact_time_span.to_timezone(Calendar.Timezone.local);
from_widget.wall_time = time_span.start_exact_time.to_wall_time();
to_widget.wall_time = time_span.end_exact_time.to_wall_time();
+ } else {
+ // set to defaults in case user wants to change from all-day to timed event
+ from_widget.wall_time = Calendar.System.now.to_wall_time().round_down(15,
Calendar.TimeUnit.MINUTE);
+ if (date_span.is_same_day) {
+ // one-hour event is default
+ to_widget.wall_time = from_widget.wall_time.adjust(1, Calendar.TimeUnit.HOUR, null);
+ } else {
+ // different days, same time on each day
+ to_widget.wall_time = from_widget.wall_time;
+ }
}
- Calendar.DateSpan date_span = message.get_event_date_span(Calendar.Timezone.local);
- from_widget.date = date_span.start_date;
- to_widget.date = date_span.end_date;
-
all_day_checkbutton.active = (message.exact_time_span == null);
}
@@ -150,6 +160,22 @@ public class EventTimeSettings : Gtk.Box, Toolkit.Card {
else
summary_label.label = get_exact_time_span().to_pretty_string(date_flags, time_flags);
}
+
+ private void on_from_changed() {
+ // clamp to_widget to not allow earlier date/times than from_widget
+ to_widget.floor = new Calendar.ExactTime(Calendar.System.timezone, from_widget.date,
+ from_widget.wall_time);
+
+ on_update_summary();
+ }
+
+ private void on_to_changed() {
+ // clamp from_widget to not allow later date/times than to_widget
+ from_widget.ceiling = new Calendar.ExactTime(Calendar.System.timezone, to_widget.date,
+ to_widget.wall_time);
+
+ on_update_summary();
+ }
}
}
diff --git a/src/tests/tests-calendar-exact-time.vala b/src/tests/tests-calendar-exact-time.vala
new file mode 100644
index 0000000..7d4b9e5
--- /dev/null
+++ b/src/tests/tests-calendar-exact-time.vala
@@ -0,0 +1,63 @@
+/* Copyright 2014 Yorba Foundation
+ *
+ * This software is licensed under the GNU Lesser General Public License
+ * (version 2.1 or later). See the COPYING file in this distribution.
+ */
+
+namespace California.Tests {
+
+internal class CalendarExactTime : UnitTest.Harness {
+ private Calendar.ExactTime? now;
+ private Calendar.ExactTime? past;
+ private Calendar.ExactTime? future;
+
+ public CalendarExactTime() {
+ add_case("clamp-floor-unaltered", clamp_floor_unaltered);
+ add_case("clamp-floor-altered", clamp_floor_altered);
+ add_case("clamp-ceiling-unaltered", clamp_ceiling_unaltered);
+ add_case("clamp-ceiling-altered", clamp_ceiling_altered);
+ add_case("clamp-both-unaltered", clamp_both_unaltered);
+ add_case("clamp-both-altered", clamp_both_altered);
+ }
+
+ protected override void setup() throws Error {
+ Calendar.init();
+
+ now = Calendar.System.now;
+ past = now.adjust_time(-1, Calendar.TimeUnit.MINUTE);
+ future = now.adjust_time(1, Calendar.TimeUnit.MINUTE);
+ }
+
+ protected override void teardown() {
+ now = past = future = null;
+
+ Calendar.terminate();
+ }
+
+ private bool clamp_floor_unaltered() throws Error {
+ return now.clamp(past, null).equal_to(now);
+ }
+
+ private bool clamp_floor_altered() throws Error {
+ return now.clamp(future, null).equal_to(future);
+ }
+
+ private bool clamp_ceiling_unaltered() throws Error {
+ return now.clamp(null, future).equal_to(now);
+ }
+
+ private bool clamp_ceiling_altered() throws Error {
+ return now.clamp(null, past).equal_to(past);
+ }
+
+ private bool clamp_both_unaltered() throws Error {
+ return now.clamp(past, future).equal_to(now);
+ }
+
+ private bool clamp_both_altered() throws Error {
+ return now.clamp(past, past).equal_to(past);
+ }
+}
+
+}
+
diff --git a/src/tests/tests.vala b/src/tests/tests.vala
index 24c171e..11a3a47 100644
--- a/src/tests/tests.vala
+++ b/src/tests/tests.vala
@@ -17,6 +17,7 @@ public int run(string[] args) {
UnitTest.Harness.register(new CalendarMonthSpan());
UnitTest.Harness.register(new CalendarMonthOfYear());
UnitTest.Harness.register(new CalendarWallTime());
+ UnitTest.Harness.register(new CalendarExactTime());
UnitTest.Harness.register(new QuickAdd());
UnitTest.Harness.register(new QuickAddRecurring());
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]