1.1 --- a/imip_manager.py Sun Feb 08 01:24:49 2015 +0100
1.2 +++ b/imip_manager.py Sun Feb 08 01:26:33 2015 +0100
1.3 @@ -307,11 +307,6 @@
1.4 isinstance(dt, datetime) and babel.dates.format_datetime or babel.dates.format_date,
1.5 dt, format)
1.6
1.7 - def format_end_datetime(self, dt, format):
1.8 - if isinstance(dt, date) and not isinstance(dt, datetime):
1.9 - dt = dt - timedelta(1)
1.10 - return self.format_datetime(dt, format)
1.11 -
1.12 def _format_datetime(self, fn, dt, format):
1.13 return fn(dt, format=format, locale=self.get_user_locale())
1.14
1.15 @@ -485,27 +480,40 @@
1.16 # Obtain the user's timezone and process datetime values.
1.17
1.18 update = False
1.19 - error = False
1.20
1.21 if is_organiser:
1.22 t = self.handle_date_controls("dtstart")
1.23 if t:
1.24 - dtstart, tzid = t
1.25 - update = update or self.set_datetime_in_object(dtstart, tzid, "DTSTART", obj)
1.26 + dtstart, attr = t
1.27 + update = update or self.set_datetime_in_object(dtstart, attr["TZID"], "DTSTART", obj)
1.28 else:
1.29 - error = True
1.30 + return False
1.31 +
1.32 + # Handle specified end datetimes.
1.33 +
1.34 + if args.get("dtend-control", [None])[0] == "enable":
1.35 + t = self.handle_date_controls("dtend")
1.36 + if t:
1.37 + dtend, attr = t
1.38 +
1.39 + # Convert end dates to iCalendar "next day" dates.
1.40
1.41 - t = self.handle_date_controls("dtend")
1.42 - if t:
1.43 - dtend, tzid = t
1.44 - update = update or self.set_datetime_in_object(dtend, tzid, "DTEND", obj)
1.45 + if not isinstance(dtend, datetime):
1.46 + dtend += timedelta(1)
1.47 + update = update or self.set_datetime_in_object(dtend, attr["TZID"], "DTEND", obj)
1.48 + else:
1.49 + return False
1.50 +
1.51 + # Otherwise, treat the end date as the start date. Datetimes cannot
1.52 + # be duplicated in such a way.
1.53 +
1.54 else:
1.55 - error = True
1.56 + if isinstance(dtstart, datetime):
1.57 + return False
1.58 + dtend = dtstart + timedelta(1)
1.59 + update = update or self.set_datetime_in_object(dtend, attr["TZID"], "DTEND", obj)
1.60
1.61 - if not error:
1.62 - error = dtstart > dtend
1.63 -
1.64 - if error:
1.65 + if dtstart >= dtend:
1.66 return False
1.67
1.68 # Process any action.
1.69 @@ -554,7 +562,7 @@
1.70
1.71 """
1.72 Handle date control information for fields starting with 'name',
1.73 - returning a (datetime, tzid) tuple or None if the fields cannot be used
1.74 + returning a (datetime, attr) tuple or None if the fields cannot be used
1.75 to construct a datetime object.
1.76 """
1.77
1.78 @@ -570,9 +578,10 @@
1.79
1.80 time = (hour or minute or second) and "T%s%s%s" % (hour, minute, second) or ""
1.81 value = "%s%s" % (date, time)
1.82 - dt = get_datetime(value, {"TZID" : tzid})
1.83 + attr = {"TZID" : tzid}
1.84 + dt = get_datetime(value, attr)
1.85 if dt:
1.86 - return dt, tzid
1.87 + return dt, attr
1.88
1.89 return None
1.90
1.91 @@ -668,6 +677,38 @@
1.92
1.93 tzid = self.get_tzid()
1.94
1.95 + # Provide controls to change the displayed object.
1.96 +
1.97 + args = self.env.get_args()
1.98 +
1.99 + t = self.handle_date_controls("dtstart")
1.100 + if t:
1.101 + dtstart, dtstart_attr = t
1.102 + else:
1.103 + dtstart, dtstart_attr = obj.get_datetime_item("DTSTART")
1.104 +
1.105 + dtend, dtend_attr = None, None
1.106 +
1.107 + if args.get("dtend-control", [None])[0] == "enable":
1.108 + t = self.handle_date_controls("dtend")
1.109 + if t:
1.110 + dtend, dtend_attr = t
1.111 + elif not args.has_key("dtend-control"):
1.112 + dtend, dtend_attr = obj.get_datetime_item("DTEND")
1.113 +
1.114 + # Change end dates to refer to the actual dates, not the iCalendar
1.115 + # "next day" dates.
1.116 +
1.117 + if dtend and not isinstance(dtend, datetime):
1.118 + dtend -= timedelta(1)
1.119 +
1.120 + if isinstance(dtend, datetime) or dtstart != dtend:
1.121 + page.input(name="dtend-control", type="radio", value="enable", id="dtend-enable", checked="checked")
1.122 + page.input(name="dtend-control", type="radio", value="disable", id="dtend-disable")
1.123 + else:
1.124 + page.input(name="dtend-control", type="radio", value="enable", id="dtend-enable")
1.125 + page.input(name="dtend-control", type="radio", value="disable", id="dtend-disable", checked="checked")
1.126 +
1.127 # Provide a summary of the object.
1.128
1.129 page.table(class_="object", cellspacing=5, cellpadding=5)
1.130 @@ -686,16 +727,30 @@
1.131 # Handle datetimes specially.
1.132
1.133 if name in ["DTSTART", "DTEND"]:
1.134 - value, attr = obj.get_item(name)
1.135 - event_tzid = attr.get("TZID", tzid)
1.136 - strvalue = (
1.137 - name == "DTSTART" and self.format_datetime or self.format_end_datetime
1.138 - )(to_timezone(get_datetime(value), event_tzid), "full")
1.139 - page.th(label, class_="objectheading")
1.140 +
1.141 + page.th(label, class_="objectheading %s" % name.lower())
1.142 +
1.143 + if name == "DTSTART":
1.144 + dt, attr, event_tzid = dtstart, dtstart_attr, dtstart_attr.get("TZID", tzid)
1.145 + else:
1.146 + dt, attr, event_tzid = dtend, dtend_attr, dtend_attr.get("TZID", tzid)
1.147 +
1.148 + strvalue = self.format_datetime(dt, "full")
1.149 + value = format_datetime(dt)
1.150
1.151 if is_organiser:
1.152 - page.td()
1.153 + page.td(class_="objectvalue %s" % name.lower())
1.154 + if name == "DTEND":
1.155 + page.div(class_="disabled")
1.156 + page.label("Specify end date", for_="dtend-enable", class_="enable")
1.157 + page.div.close()
1.158 +
1.159 + page.div(class_="enabled")
1.160 self._show_date_controls(name.lower(), value, attr, tzid)
1.161 + if name == "DTEND":
1.162 + page.label("End on same day", for_="dtend-disable", class_="disable")
1.163 + page.div.close()
1.164 +
1.165 page.td.close()
1.166 else:
1.167 page.td(strvalue)
1.168 @@ -705,7 +760,8 @@
1.169 # Handle the summary specially.
1.170
1.171 elif name == "SUMMARY":
1.172 - value = obj.get_value(name)
1.173 + value = args.get("summary", [obj.get_value(name)])[0]
1.174 +
1.175 page.th(label, class_="objectheading")
1.176 page.td()
1.177 if is_organiser: