[california] Reflect new event dates in updated event: Closes bug #729897



commit e06c5cfbf8153a456a1dcbbfc46bf6c3f5ef4118
Author: Jim Nelson <jim yorba org>
Date:   Fri May 9 17:58:50 2014 -0700

    Reflect new event dates in updated event: Closes bug #729897
    
    Two problems: When event was altered, it was removed from old dates
    but not added to new dates.  Also, when updated, existing event wasn't
    being located properly.

 .../backing-calendar-subscription-manager.vala     |   13 +++++++
 .../backing-eds-calendar-source-subscription.vala  |   26 ++++++++++++-
 src/component/component-event.vala                 |   22 -----------
 src/component/component-uid.vala                   |    4 +-
 src/view/month/month-grid.vala                     |   38 +++++++++++++-------
 5 files changed, 64 insertions(+), 39 deletions(-)
---
diff --git a/src/backing/backing-calendar-subscription-manager.vala 
b/src/backing/backing-calendar-subscription-manager.vala
index d686310..71da1b4 100644
--- a/src/backing/backing-calendar-subscription-manager.vala
+++ b/src/backing/backing-calendar-subscription-manager.vala
@@ -48,6 +48,14 @@ public class CalendarSubscriptionManager : BaseObject {
     public signal void instance_added(Component.Instance instance);
     
     /**
+     * Indicates the { link Component.Instance} was reported altered by one of the managed
+     * subscriptions, either by the local user or on a remote server.
+     *
+     * @see Component.Instance.altered
+     */
+    public signal void instance_altered(Component.Instance instance);
+    
+    /**
      * Indicates the { link Component.Instance} was removed by one of the managed subscriptions,
      * either due to the { link CalendarSource} being made unavailable or removal by the user.
      */
@@ -131,6 +139,7 @@ public class CalendarSubscriptionManager : BaseObject {
             subscription.instance_added.connect(on_instance_added);
             subscription.instance_removed.connect(on_instance_removed);
             subscription.instance_dropped.connect(on_instance_removed);
+            subscription.instance_altered.connect(on_instance_altered);
             subscription.start_failed.connect(on_error);
             
             // this will start signals firing for event changes
@@ -152,6 +161,10 @@ public class CalendarSubscriptionManager : BaseObject {
         instance_removed(instance);
     }
     
+    private void on_instance_altered(Component.Instance instance) {
+        instance_altered(instance);
+    }
+    
     private void on_error(CalendarSourceSubscription subscription, Error err) {
         subscription_error(subscription.calendar, err);
     }
diff --git a/src/backing/eds/backing-eds-calendar-source-subscription.vala 
b/src/backing/eds/backing-eds-calendar-source-subscription.vala
index 8378711..f531a39 100644
--- a/src/backing/eds/backing-eds-calendar-source-subscription.vala
+++ b/src/backing/eds/backing-eds-calendar-source-subscription.vala
@@ -128,8 +128,30 @@ internal class EdsCalendarSourceSubscription : CalendarSourceSubscription {
             
             // only update known objects
             string? uid = ical_component.get_uid();
-            if (!String.is_empty(uid))
-                event = for_uid(new Component.UID(uid)) as Component.Event;
+            if (!String.is_empty(uid)) {
+                Gee.Collection<Component.Instance>? instances = for_uid(new Component.UID(uid));
+                if (instances != null && instances.size > 0) {
+                    // convert the modified event source into an orphaned event
+                    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);
+                        
+                        continue;
+                    }
+                    
+                    // for every instance matching its UID, look for the original
+                    foreach (Component.Instance instance in instances) {
+                        Component.Event? stored_event = instance as Component.Event;
+                        if (stored_event != null && stored_event.equal_to(modified_event)) {
+                            event = stored_event;
+                            
+                            break;
+                        }
+                    }
+                }
+            }
             
             if (event == null)
                 continue;
diff --git a/src/component/component-event.vala b/src/component/component-event.vala
index a54834e..a2fc8c2 100644
--- a/src/component/component-event.vala
+++ b/src/component/component-event.vala
@@ -337,28 +337,6 @@ public class Event : Instance, Gee.Comparable<Event> {
         if (sequence != other_event.sequence)
             return false;
         
-        if (exact_time_span != null && other_event.exact_time_span != null
-            && !exact_time_span.equal_to(other_event.exact_time_span)) {
-            return false;
-        }
-        
-        if (date_span != null && other_event.date_span != null
-            && !date_span.equal_to(other_event.date_span)) {
-            return false;
-        }
-        
-        if (exact_time_span != null
-            && other_event.date_span != null
-            && !new Calendar.DateSpan.from_exact_time_span(exact_time_span).equal_to(other_event.date_span)) 
{
-            return false;
-        }
-        
-        if (date_span != null
-            && other_event.exact_time_span != null
-            && !date_span.equal_to(new Calendar.DateSpan.from_exact_time_span(other_event.exact_time_span))) 
{
-            return false;
-        }
-        
         return base.equal_to(other);
     }
     
diff --git a/src/component/component-uid.vala b/src/component/component-uid.vala
index 758f961..98e5364 100644
--- a/src/component/component-uid.vala
+++ b/src/component/component-uid.vala
@@ -37,7 +37,7 @@ public class UID : BaseObject, Gee.Hashable<UID>, Gee.Comparable<UID> {
     }
     
     public bool equal_to(UID other) {
-        return (this != other) ? value == other.value : true;
+        return compare_to(other) == 0;
     }
     
     /**
@@ -47,7 +47,7 @@ public class UID : BaseObject, Gee.Hashable<UID>, Gee.Comparable<UID> {
      * used to stabilize sorts of { link Instance}s.
      */
     public int compare_to(UID other) {
-        return strcmp(value, other.value);
+        return (this != other) ? strcmp(value, other.value) : 0;
     }
     
     public override string to_string() {
diff --git a/src/view/month/month-grid.vala b/src/view/month/month-grid.vala
index fd76f99..8661140 100644
--- a/src/view/month/month-grid.vala
+++ b/src/view/month/month-grid.vala
@@ -128,6 +128,14 @@ private class Grid : Gtk.Grid {
         }
     }
     
+    private void foreach_cell_in_date_span(Calendar.DateSpan span, CellCallback callback) {
+        foreach (Calendar.Date date in span) {
+            Cell? cell = date_to_cell.get(date);
+            if (cell != null && !callback(cell))
+                return;
+        }
+    }
+    
     // Must be in coordinates of the Gtk.Grid, not a Cell
     private Cell? translate_to_cell(int grid_x, int grid_y) {
         // TODO: A proper hit-detection algorithm would be better here
@@ -192,7 +200,8 @@ private class Grid : Gtk.Grid {
         subscriptions = new Backing.CalendarSubscriptionManager(time_window);
         subscriptions.calendar_added.connect(on_calendar_added);
         subscriptions.calendar_removed.connect(on_calendar_removed);
-        subscriptions.instance_added.connect(on_instance_added);
+        subscriptions.instance_added.connect(on_instance_added_or_altered);
+        subscriptions.instance_altered.connect(on_instance_added_or_altered);
         subscriptions.instance_removed.connect(on_instance_removed);
         
         // only start if this month is being displayed, otherwise will be started when owner's
@@ -259,17 +268,19 @@ private class Grid : Gtk.Grid {
         });
     }
     
-    private void on_instance_added(Component.Instance instance) {
+    private void on_instance_added_or_altered(Component.Instance instance) {
         Component.Event? event = instance as Component.Event;
         if (event == null)
             return;
         
-        // add event to every date it represents
-        foreach (Calendar.Date date in event.get_event_date_span(Calendar.Timezone.local)) {
-            Cell? cell = date_to_cell.get(date);
-            if (cell != null)
-                cell.add_event(event);
-        }
+        // add event to every date it represents ... in the "instance-altered" case, if the event's
+        // date changes it doesn't need to be removed here (Month.Call catches the change and
+        // removes it itself) but it does need to be added to the new date(s) it covers
+        foreach_cell_in_date_span(event.get_event_date_span(Calendar.Timezone.local), (cell) => {
+            cell.add_event(event);
+            
+            return true;
+        });
     }
     
     private void on_instance_removed(Component.Instance instance) {
@@ -277,11 +288,12 @@ private class Grid : Gtk.Grid {
         if (event == null)
             return;
         
-        foreach (Calendar.Date date in event.get_event_date_span(Calendar.Timezone.local)) {
-            Cell? cell = date_to_cell.get(date);
-            if (cell != null)
-                cell.remove_event(event);
-        }
+        // remove event from every date it represents
+        foreach_cell_in_date_span(event.get_event_date_span(Calendar.Timezone.local), (cell) => {
+            cell.remove_event(event);
+            
+            return true;
+        });
     }
     
     public void unselect_all() {


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