[california/wip/725787-remove-recurring] Clean up how Backing.Eds deals with signals



commit 35f58ed7f99a2a7934272944690298466243cb1c
Author: Jim Nelson <jim yorba org>
Date:   Wed Jul 2 16:42:16 2014 -0700

    Clean up how Backing.Eds deals with signals
    
    Looking over Evolution code, I saw that how we were dealing with
    signals from CalClientView wasn't exactly right.

 src/backing/backing-calendar-source.vala           |    3 +
 .../backing-eds-calendar-source-subscription.vala  |   89 +++++++++++++-------
 vapi/libecal-1.2.vapi                              |    8 ++
 vapi/libecal-1.2/libecal-1.2-custom.vala           |   18 ++++
 4 files changed, 89 insertions(+), 29 deletions(-)
---
diff --git a/src/backing/backing-calendar-source.vala b/src/backing/backing-calendar-source.vala
index 4286b67..44ae06a 100644
--- a/src/backing/backing-calendar-source.vala
+++ b/src/backing/backing-calendar-source.vala
@@ -89,6 +89,9 @@ public abstract class CalendarSource : Source {
      * { link CalendarSource} keyed to the supplied { link Component.UID}, the supplied RID,
      * and the { link AffectedInstances}.
      *
+     * If { link AffectedInstances.ALL} is passed, the RID is ignored.  This is operationally the
+     * same as calling { link remove_all_instances_async}.
+     *
      * Outstanding { link CalendarSourceSubscriptions} will eventually report all affected instances
      * as removed.
      */
diff --git a/src/backing/eds/backing-eds-calendar-source-subscription.vala 
b/src/backing/eds/backing-eds-calendar-source-subscription.vala
index 0da9af6..b3003a6 100644
--- a/src/backing/eds/backing-eds-calendar-source-subscription.vala
+++ b/src/backing/eds/backing-eds-calendar-source-subscription.vala
@@ -112,6 +112,23 @@ internal class EdsCalendarSourceSubscription : CalendarSourceSubscription {
     
     private void on_objects_added(SList<weak iCal.icalcomponent> objects) {
         foreach (weak iCal.icalcomponent ical_component in objects) {
+            if (String.is_empty(ical_component.get_uid()))
+                continue;
+            
+            Component.UID uid = new Component.UID(ical_component.get_uid());
+            
+            // remove all existing components with this UID
+            if (has_uid(uid))
+                notify_instance_removed(uid);
+            
+            // if no recurrences, add this alone
+            if (!E.Util.component_has_recurrences(ical_component)) {
+                add_instance(ical_component);
+                
+                continue;
+            }
+            
+            // generate recurring instances
             view.client.generate_instances_for_object(
                 ical_component,
                 window.start_exact_time.to_time_t(),
@@ -124,56 +141,70 @@ internal class EdsCalendarSourceSubscription : CalendarSourceSubscription {
     
     private bool on_instance_added(E.CalComponent eds_component, time_t instance_start,
         time_t instance_end) {
-        unowned iCal.icalcomponent ical_component = eds_component.get_icalcomponent();
+        add_instance(eds_component.get_icalcomponent());
         
+        return true;
+    }
+    
+    // Assumes all existing events with UID/RID have been removed already
+    private void add_instance(iCal.icalcomponent ical_component) {
         // convert the added component into a new Event
         Component.Event? added_event;
         try {
             added_event = Component.Instance.convert(calendar, ical_component) as Component.Event;
-            if (added_event == null)
-                return true;
+            if (added_event != null)
+                notify_instance_added(added_event);
         } catch (Error err) {
             debug("Unable to process added event: %s", err.message);
-            
-            return true;
         }
-        
-        // see if this was seen before
-        Component.Event? seen_event = has_instance(added_event) as Component.Event;
-        if (seen_event != null)
-            return true;
-        
-        // nope, it's a new one
-        notify_instance_added(added_event);
-        
-        return true;
     }
     
     private void on_objects_modified(SList<weak iCal.icalcomponent> objects) {
+        SList<weak iCal.icalcomponent> add_list = new SList<weak iCal.icalcomponent>();
         foreach (weak iCal.icalcomponent ical_component in objects) {
-            // convert the modified event source into an orphaned event (for comparison purposes)
-            Component.Event modified_event;
-            try {
-                modified_event = new Component.Event(null, ical_component);
-            } catch (Error err) {
-                debug("Unable to process modified event: %s", err.message);
+            // if not an instance and has recurring, treat as an add (which removes and adds generated
+            // instances)
+            if (!E.Util.component_is_instance(ical_component) && 
E.Util.component_has_recurrences(ical_component)) {
+                add_list.append(ical_component);
                 
                 continue;
             }
             
-            // find original event instance for this one
-            Component.Event? seen_event = has_instance(modified_event) as Component.Event;
-            if (seen_event == null)
+            if (String.is_empty(ical_component.get_uid()))
+                continue;
+            
+            // if none present, skip
+            Component.UID uid = new Component.UID(ical_component.get_uid());
+            if (!has_uid(uid))
                 continue;
             
-            try {
-                seen_event.full_update(ical_component, null);
-            } catch (Error err) {
-                debug("Unable to update event %s: %s", seen_event.to_string(), err.message);
+            // find original for this one
+            Gee.Collection<Component.Instance>? instances = for_uid(uid);
+            if (instances == null || instances.size == 0)
+                continue;
+            
+            foreach (Component.Instance instance in instances) {
+                Component.Event? known_event = instance as Component.Event;
+                if (known_event == null)
+                    continue;
+                
+                try {
+                    known_event.full_update(ical_component, null);
+                } catch (Error err) {
+                    debug("Unable to update event %s: %s", known_event.to_string(), err.message);
+                    
+                    continue;
+                }
+                
+                notify_instance_altered(known_event);
             }
             
-            notify_instance_altered(seen_event);
+            if (instances.size > 1)
+                debug("Warning: updated %d modified events, expecting only 1", instances.size);
         }
+        
+        // add any recurring events
+        on_objects_added(add_list);
     }
     
     private void on_objects_removed(SList<weak E.CalComponentId?> ids) {
diff --git a/vapi/libecal-1.2.vapi b/vapi/libecal-1.2.vapi
index 7952301..54894e7 100644
--- a/vapi/libecal-1.2.vapi
+++ b/vapi/libecal-1.2.vapi
@@ -2,6 +2,14 @@
 
 [CCode (cprefix = "E", gir_namespace = "ECalendar", gir_version = "1.2", lower_case_cprefix = "e_")]
 namespace E {
+       namespace Util {
+               [CCode (cheader_filename = "libecal/libecal.h", cname = 
"e_cal_util_component_has_recurrences")]
+               public static bool component_has_recurrences (iCal.icalcomponent ical_component);
+               [CCode (cheader_filename = "libecal/libecal.h", cname = "e_cal_util_component_is_instance")]
+               public static bool component_is_instance (iCal.icalcomponent ical_component);
+               [CCode (cheader_filename = "libecal/libecal.h", cname = "e_cal_util_remove_instances")]
+               public static bool remove_instances (iCal.icalcomponent ical_component, iCal.icaltimetype 
rid, E.CalObjModType mod);
+       }
        [CCode (cheader_filename = "libecal/libecal.h", type_id = "e_cal_client_get_type ()")]
        public class CalClient : E.Client, GLib.Initable, GLib.AsyncInitable, E.TimezoneCache {
                [CCode (has_construct_function = false)]
diff --git a/vapi/libecal-1.2/libecal-1.2-custom.vala b/vapi/libecal-1.2/libecal-1.2-custom.vala
index e69de29..791263b 100644
--- a/vapi/libecal-1.2/libecal-1.2-custom.vala
+++ b/vapi/libecal-1.2/libecal-1.2-custom.vala
@@ -0,0 +1,18 @@
+/* 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 E.Util {
+
+[CCode (cheader_filename="libecal/libecal.h", cname="e_cal_util_component_has_recurrences")]
+public bool component_has_recurrences(iCal.icalcomponent ical_component);
+
+[CCode (cheader_filename="libecal/libecal.h", cname="e_cal_util_component_is_instance")]
+public bool component_is_instance(iCal.icalcomponent ical_component);
+
+[CCode (cheader_filename="libecal/libecal.h", cname="e_cal_util_remove_instances")]
+public bool remove_instances(iCal.icalcomponent ical_component, iCal.icaltimetype rid, E.CalObjModType mod);
+
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]