[california/wip/725787-remove-recurring] Improvements
- From: Jim Nelson <jnelson src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [california/wip/725787-remove-recurring] Improvements
- Date: Thu, 3 Jul 2014 02:28:08 +0000 (UTC)
commit 0ef789a0c33bebd92294d55f9da26b9e4df456f1
Author: Jim Nelson <jim yorba org>
Date: Wed Jul 2 19:27:57 2014 -0700
Improvements
src/backing/eds/backing-eds-calendar-source.vala | 119 ++++++++++++++++------
src/component/component-date-time.vala | 2 +-
src/host/host-show-event.vala | 2 +
vapi/libecal-1.2.vapi | 3 +-
vapi/libecal-1.2/libecal-1.2.metadata | 7 +-
vapi/libical.vapi | 6 +-
6 files changed, 101 insertions(+), 38 deletions(-)
---
diff --git a/src/backing/eds/backing-eds-calendar-source.vala
b/src/backing/eds/backing-eds-calendar-source.vala
index 292359e..f68da03 100644
--- a/src/backing/eds/backing-eds-calendar-source.vala
+++ b/src/backing/eds/backing-eds-calendar-source.vala
@@ -118,31 +118,6 @@ internal class EdsCalendarSource : CalendarSource {
read_only = true;
}
- // Note that E.CalObjModType.ONLY_THIS is *never* returned ... examining EDS source code,
- // it appears in e-cal-backend-file.c that ONLY_THIS merely removes the instance but does not
- // include an EXDATE in the original iCal source ... I don't quite understand the benefit of
- // this, as this suggests (a) other calendar clients won't learn of the removal and (b) the
- // instance will be re-generated the next time the user runs an EDS calendar client. In either
- // case, ONLY maps to our desired effect by adding an EXDATE to the iCal source.
- private E.CalObjModType convert_to_obj_mod_type(CalendarSource.AffectedInstances affected) {
- switch (affected) {
- case CalendarSource.AffectedInstances.THIS:
- return E.CalObjModType.THIS;
-
- case CalendarSource.AffectedInstances.THIS_AND_FUTURE:
- return E.CalObjModType.THIS_AND_FUTURE;
-
- case CalendarSource.AffectedInstances.THIS_AND_PRIOR:
- return E.CalObjModType.THIS_AND_PRIOR;
-
- case CalendarSource.AffectedInstances.ALL:
- return E.CalObjModType.ALL;
-
- default:
- assert_not_reached();
- }
- }
-
private void check_open() throws BackingError {
if (client == null)
throw new BackingError.UNAVAILABLE("%s has been removed", to_string());
@@ -191,15 +166,95 @@ internal class EdsCalendarSource : CalendarSource {
CalendarSource.AffectedInstances affected, Cancellable? cancellable = null) throws Error {
check_open();
- E.CalObjModType mod_type = convert_to_obj_mod_type(affected);
+ // Note that E.CalObjModType.ONLY_THIS is *never* used ... examining EDS source code,
+ // it appears in e-cal-backend-file.c that ONLY_THIS merely removes the instance but does not
+ // include an EXDATE in the original iCal source ... I don't quite understand the benefit of
+ // this, as this suggests (a) other calendar clients won't learn of the removal and (b) the
+ // instance will be re-generated the next time the user runs an EDS calendar client. In
+ // either case, ONLY maps to our desired effect by adding an EXDATE to the iCal source.
+ switch (affected) {
+ case CalendarSource.AffectedInstances.THIS:
+ yield client.remove_object(uid.value, rid.value, E.CalObjModType.THIS, cancellable);
+ break;
+
+ case CalendarSource.AffectedInstances.THIS_AND_FUTURE:
+ yield remove_future_async(uid, rid, cancellable);
+ break;
+
+ case CalendarSource.AffectedInstances.THIS_AND_PRIOR:
+ yield remove_prior_async(uid, rid, cancellable);
+ break;
+
+ case CalendarSource.AffectedInstances.ALL:
+ yield remove_all_instances_async(uid, cancellable);
+ break;
+
+ default:
+ assert_not_reached();
+ }
+ }
+
+ private async void remove_future_async(Component.UID uid, Component.DateTime rid,
+ Cancellable? cancellable) throws Error {
+ // get the master instance ... remember that the Backing.CalendarSource only stores generated
+ // instances
+ iCal.icalcomponent ical_component;
+ yield client.get_object(uid.value, null, cancellable, out ical_component);
+
+ // change the RRULE's UNTIL indicating the end of the recurring set (which is, handily enough,
+ // the RID)
+ unowned iCal.icalproperty? rrule_property = ical_component.get_first_property(
+ iCal.icalproperty_kind.RRULE_PROPERTY);
+ if (rrule_property == null)
+ return;
+
+ iCal.icalrecurrencetype rrule = rrule_property.get_rrule();
+
+ // In order to be inclusive, need to set UNTIL one tick earlier to ensure the supplied RID
+ // is now excluded
+ if (rid.is_date) {
+ Component.date_to_ical(rid.to_date().previous(), &rrule.until);
+ } else {
+ Component.exact_time_to_ical(rid.to_exact_time().adjust_time(-1, Calendar.TimeUnit.SECOND),
+ &rrule.until);
+ }
+
+ // COUNT and UNTIL are mutually exclusive in an RRULE ... COUNT can be reliably reset
+ // because the RID enforces a new de facto COUNT (assuming the RID originated from the UID's
+ // recurring instance; if not, the user has screwed up)
+ rrule.count = 0;
+
+ rrule_property.set_rrule(rrule);
+
+ // write it out ... essentially, this style of remove is actually an update
+ yield client.modify_object(ical_component, E.CalObjModType.THIS, cancellable);
+ }
+
+ private async void remove_prior_async(Component.UID uid, Component.DateTime rid,
+ Cancellable? cancellable) throws Error {
+ // get the master instance ... remember that the Backing.CalendarSource only stores generated
+ // instances
+ iCal.icalcomponent ical_component;
+ yield client.get_object(uid.value, null, cancellable, out ical_component);
+
+ // like remove_future_async(), need to set DTSTART one tick forward to ensure the supplied
+ // RID is now excluded
+ //
+ // TODO: DTSTART needs to be synchronized with recurrences, so this is a no-go
+ iCal.icaltimetype dtstart = {};
+ if (rid.is_date) {
+ Component.date_to_ical(rid.to_date().next(), &dtstart);
+ } else {
+ Component.exact_time_to_ical(rid.to_exact_time().adjust_time(1, Calendar.TimeUnit.SECOND),
+ &dtstart);
+ }
- debug("remove_instances_async: UID=%s RID=%s MOD_TYPE=%Xh", uid.value, rid.value, mod_type);
+ // change the DTSTART indicating the start of the recurring set (which is, handily enough,
+ // the RID)
+ ical_component.set_dtstart(dtstart);
- // special-case ALL
- if (mod_type == E.CalObjModType.ALL)
- yield remove_all_instances_async(uid, cancellable);
- else
- yield client.remove_object(uid.value, rid.value, mod_type, cancellable);
+ // write it out ... essentially, this style of remove is actually an update
+ yield client.modify_object(ical_component, E.CalObjModType.THIS, cancellable);
}
public override async void import_icalendar_async(Component.iCalendar ical, Cancellable? cancellable =
null)
diff --git a/src/component/component-date-time.vala b/src/component/component-date-time.vala
index 0a64cbc..d52bd00 100644
--- a/src/component/component-date-time.vala
+++ b/src/component/component-date-time.vala
@@ -169,7 +169,7 @@ public class DateTime : BaseObject, Gee.Hashable<DateTime>, Gee.Comparable<DateT
*
* Returns null if { link is_date} is true.
*/
- public Calendar.ExactTime? to_exact_time() throws CalendarError{
+ public Calendar.ExactTime? to_exact_time() throws CalendarError {
if (is_date)
return null;
diff --git a/src/host/host-show-event.vala b/src/host/host-show-event.vala
index 142a402..deced98 100644
--- a/src/host/host-show-event.vala
+++ b/src/host/host-show-event.vala
@@ -69,6 +69,8 @@ public class ShowEvent : Gtk.Grid, Toolkit.Card {
}
private void build_display() {
+ debug("%s\n", event.source);
+
// summary
set_label(null, summary_text, event.summary);
diff --git a/vapi/libecal-1.2.vapi b/vapi/libecal-1.2.vapi
index 54894e7..4d9a21a 100644
--- a/vapi/libecal-1.2.vapi
+++ b/vapi/libecal-1.2.vapi
@@ -51,7 +51,8 @@ namespace E {
public async bool get_free_busy (ulong start, ulong end, GLib.SList users, GLib.Cancellable?
cancellable) throws GLib.Error;
public bool get_free_busy_sync (ulong start, ulong end, GLib.SList users, GLib.Cancellable?
cancellable) throws GLib.Error;
public unowned string get_local_attachment_store ();
- public async bool get_object (string uid, string rid, GLib.Cancellable? cancellable, out
unowned iCal.icalcomponent out_icalcomp) throws GLib.Error;
+ [CCode (finish_name = "e_cal_client_get_object_finish")]
+ public async void get_object (string uid, string? rid, GLib.Cancellable? cancellable, out
iCal.icalcomponent out_icalcomp) throws GLib.Error;
public async bool get_object_list (string sexp, GLib.Cancellable? cancellable) throws
GLib.Error;
public async bool get_object_list_as_comps (string sexp, GLib.Cancellable? cancellable)
throws GLib.Error;
public bool get_object_list_as_comps_sync (string sexp, GLib.SList out_ecalcomps,
GLib.Cancellable? cancellable) throws GLib.Error;
diff --git a/vapi/libecal-1.2/libecal-1.2.metadata b/vapi/libecal-1.2/libecal-1.2.metadata
index 951af62..e93a428 100644
--- a/vapi/libecal-1.2/libecal-1.2.metadata
+++ b/vapi/libecal-1.2/libecal-1.2.metadata
@@ -82,9 +82,12 @@ e_cal_client_get_free_busy async="1"
e_cal_client_get_free_busy.cancellable nullable="1"
e_cal_client_get_free_busy_sync.cancellable nullable="1"
-e_cal_client_get_object async="1"
+e_cal_client_get_object async="1" finish_name="e_cal_client_get_object_finish"
+e_cal_client_get_object.rid nullable="1"
e_cal_client_get_object.cancellable nullable="1"
-e_cal_client_get_object_finish.icalcomp is_out="1" value_owned="1"
+
+e_cal_client_get_object_finish type_name="void"
+e_cal_client_get_object_finish.out_icalcomp is_out="1" transfer_ownership="1"
e_cal_client_get_object_list async="1"
e_cal_client_get_object_list.cancellable nullable="1"
diff --git a/vapi/libical.vapi b/vapi/libical.vapi
index 2bf00a2..9b50119 100644
--- a/vapi/libical.vapi
+++ b/vapi/libical.vapi
@@ -1678,7 +1678,8 @@ namespace iCal {
[Compact]
public class sspm_minor_type {
}
- [CCode (cheader_filename = "libical/ical.h")]
+ [CCode (cheader_filename = "libical/ical.h", cname="struct icaldatetimeperiodtype")]
+ [SimpleType]
public struct icaldatetimeperiodtype {
public iCal.icaltimetype time;
public iCal.icalperiodtype period;
@@ -1688,7 +1689,8 @@ namespace iCal {
public float lat;
public float lon;
}
- [CCode (cheader_filename = "libical/ical.h")]
+ [CCode (cheader_filename = "libical/ical.h", cname="struct icalperiodtype")]
+ [SimpleType]
public struct icalperiodtype {
public iCal.icaltimetype start;
public iCal.icaltimetype end;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]