1.1 --- a/imipweb/event.py Mon Sep 28 17:04:03 2015 +0200
1.2 +++ b/imipweb/event.py Mon Sep 28 22:16:16 2015 +0200
1.3 @@ -60,6 +60,12 @@
1.4 without notification.
1.5 """
1.6
1.7 + return self.can_edit_recurrence(recurrence) and not recurrence.origin
1.8 +
1.9 + def can_edit_recurrence(self, recurrence):
1.10 +
1.11 + "Return whether 'recurrence' can be edited."
1.12 +
1.13 return self.recurrence_is_new(recurrence) or not self.obj.is_shared()
1.14
1.15 def recurrence_is_new(self, recurrence):
1.16 @@ -193,6 +199,7 @@
1.17
1.18 recurrenceids = self._get_active_recurrences(self.uid)
1.19 replaced = not self.recurrenceid and period.is_replaced(recurrenceids)
1.20 + excluded = period not in self.get_periods(self.obj)
1.21
1.22 # Provide a summary of the object.
1.23
1.24 @@ -221,7 +228,7 @@
1.25 # Handle datetimes specially.
1.26
1.27 if name in ["DTSTART", "DTEND"]:
1.28 - if not replaced:
1.29 + if not replaced and not excluded:
1.30
1.31 # Obtain the datetime.
1.32
1.33 @@ -234,9 +241,22 @@
1.34 self.show_datetime_controls(is_start and period.get_form_start() or period.get_form_end(), is_start)
1.35
1.36 elif name == "DTSTART":
1.37 - page.td(class_="objectvalue %s replaced" % field, rowspan=2)
1.38 - page.a("First occurrence replaced by a separate event", href=self.link_to(self.uid, replaced))
1.39 - page.td.close()
1.40 +
1.41 + # Replaced occurrences link to their replacements.
1.42 +
1.43 + if replaced:
1.44 + page.td(class_="objectvalue %s replaced" % field, rowspan=2)
1.45 + page.a("First occurrence replaced by a separate event", href=self.link_to(self.uid, replaced))
1.46 + page.td.close()
1.47 +
1.48 + # NOTE: Should provide a way of editing recurrences when the
1.49 + # NOTE: first occurrence is excluded, plus a way of
1.50 + # NOTE: reinstating the occurrence.
1.51 +
1.52 + elif excluded:
1.53 + page.td(class_="objectvalue %s excluded" % field, rowspan=2)
1.54 + page.add("First occurrence excluded")
1.55 + page.td.close()
1.56
1.57 page.tr.close()
1.58
1.59 @@ -474,7 +494,8 @@
1.60 page.th("")
1.61 page.td()
1.62
1.63 - remove_type = (not self.obj.is_shared() or not period.origin) and "submit" or "checkbox"
1.64 + remove_type = self.can_remove_recurrence(period) and "submit" or "checkbox"
1.65 +
1.66 self.control("recur-remove", remove_type, str(index),
1.67 str(index) in args.get("recur-remove", []),
1.68 id="recur-remove-%d" % index, class_="remove")
1.69 @@ -715,10 +736,11 @@
1.70 # Set the periods in the object, first obtaining removed and
1.71 # modified period information.
1.72
1.73 - to_unschedule = self.get_removed_periods(periods)
1.74 + to_unschedule, to_exclude = self.get_removed_periods(periods)
1.75
1.76 self.obj.set_period(period)
1.77 self.obj.set_periods(periods)
1.78 + self.obj.update_exceptions(to_exclude)
1.79
1.80 # Update summary.
1.81
1.82 @@ -841,14 +863,26 @@
1.83
1.84 """
1.85 Return those from the recurrence 'periods' to remove upon updating an
1.86 - event.
1.87 + event along with those to exclude in a tuple of the form (unscheduled,
1.88 + excluded).
1.89 """
1.90
1.91 + args = self.env.get_args()
1.92 to_unschedule = []
1.93 - args = self.env.get_args()
1.94 + to_exclude = []
1.95 +
1.96 for i in args.get("recur-remove", []):
1.97 - to_unschedule.append(periods[int(i)])
1.98 - return to_unschedule
1.99 + try:
1.100 + period = periods[int(i)]
1.101 + except (IndexError, ValueError):
1.102 + continue
1.103 +
1.104 + if not self.can_edit_recurrence(period):
1.105 + to_unschedule.append(period)
1.106 + else:
1.107 + to_exclude.append(period)
1.108 +
1.109 + return to_unschedule, to_exclude
1.110
1.111 def get_attendees_from_page(self):
1.112
1.113 @@ -916,7 +950,7 @@
1.114 # NOTE: Addition of recurrences to be supported.
1.115
1.116 # Only actually remove recurrences if the event is unsent, or if the
1.117 - # recurrence is new.
1.118 + # recurrence is new, but only for explicit recurrences.
1.119
1.120 if args.has_key("recur-remove"):
1.121 still_to_remove = []