Title: [commits] (stearns) [11436] Second step of several reminder changes: still no user-visible changes; added internal support for absolute reminders, as well as more than one reminder per item (only one user-visible reminder is possible, though an internal reminder will be used for dealing with the startTime-reached triageStatus transition), and updated unit tests.
Revision
11436
Author
stearns
Date
2006-08-17 11:54:38 -0700 (Thu, 17 Aug 2006)

Log Message

Second step of several reminder changes: still no user-visible changes; added internal support for absolute reminders, as well as more than one reminder per item (only one user-visible reminder is possible, though an internal reminder will be used for dealing with the startTime-reached triageStatus transition), and updated unit tests.

Modified Paths

Diff

Modified: trunk/chandler/application/Utility.py (11435 => 11436)

--- trunk/chandler/application/Utility.py	2006-08-17 18:02:08 UTC (rev 11435)
+++ trunk/chandler/application/Utility.py	2006-08-17 18:54:38 UTC (rev 11436)
@@ -33,7 +33,7 @@
 # with your name (and some helpful text). The comment's really there just to
 # cause Subversion to warn you of a conflict when you update, in case someone 
 # else changes it at the same time you do (that's why it's on the same line).
-SCHEMA_VERSION = "234" # jeffrey: Add ScrollY to TimedEventCanvas
+SCHEMA_VERSION = "235" # stearns: Reminder rework, part deux
 
 logger = None # initialized in initLogging()
 

Modified: trunk/chandler/parcels/osaf/pim/calendar/Calendar.py (11435 => 11436)

--- trunk/chandler/parcels/osaf/pim/calendar/Calendar.py	2006-08-17 18:02:08 UTC (rev 11435)
+++ trunk/chandler/parcels/osaf/pim/calendar/Calendar.py	2006-08-17 18:54:38 UTC (rev 11436)
@@ -35,7 +35,6 @@
 from TimeZone import formatTime
 from osaf.pim.calendar.TimeZone import coerceTimeZone, TimeZoneInfo
 from osaf.pim.calendar import DateTimeUtil
-from osaf.pim.reminders import Remindable, Reminder
 from PyICU import DateFormat, DateFormatSymbols, ICUtzinfo
 from datetime import datetime, time, timedelta
 import itertools
@@ -285,8 +284,8 @@
     getRecurrenceID, deleteThis, deleteThisAndFuture, deleteAll,
     removeRecurrence, isCustomRule, getCustomDescription, isAttributeModifiable
 
-    @group Comparison Methods for Indexing: cmpTimeAttribute, cmpStartTime,
-    cmpEndTime, cmpRecurEnd, cmpReminderTime
+    @group Comparison Methods for Indexing: cmpStartTime,
+    cmpEndTime, cmpRecurEnd
 
     @group Semi-Private Methods: addToCollection, changeNoModification,
     cleanRule, copyCollections, getEffectiveEndTime, getEffectiveStartTime,
@@ -931,8 +930,13 @@
 
         # ... and update the collections accordingly
         for reminder in nowExpired:
-            self.expiredReminders.add(reminder)
             self.reminders.remove(reminder)
+            if reminder.keepExpired:
+                self.expiredReminders.add(reminder)
+            else:
+                assert len(reminder.reminderItems) == 0
+                assert len(reminder.expiredReminderItems) == 0
+                reminder.delete()
 
         for reminder in nowNotExpired:
             self.reminders.add(reminder)
@@ -1580,27 +1584,6 @@
         # Otherwise, just do it the normal way.
         return super(CalendarEventMixin, self).isAttributeModifiable(attribute)
 
-    def cmpTimeAttribute(self, item, attr, useTZ=True):
-        """Compare item and self.attr, ignore timezones if useTZ is False."""
-        itemTime = getattr(item, attr, None)
-        selfTime = getattr(self, attr, None)
-
-        if itemTime is None:
-            if selfTime is None:
-                # both attributes are None, so item and self compare as equal
-                return 0
-            else:
-                return -1
-        elif not useTZ:
-            itemTime = itemTime.replace(tzinfo = None)
-
-        if selfTime is None:
-            return 1
-        elif not useTZ:
-            selfTime = selfTime.replace(tzinfo = None)
-
-        return cmp(selfTime, itemTime)
-
     # for use in indexing CalendarEventMixins
     def cmpStartTime(self, item):
         return self.cmpTimeAttribute(item, 'effectiveStartTime')
@@ -1611,9 +1594,6 @@
     def cmpRecurEnd(self, item):
         return self.cmpTimeAttribute(item, 'recurrenceEnd')
 
-    def cmpReminderTime(self, item):
-        return self.cmpTimeAttribute(item, 'reminderFireTime')
-
     # comparisons which strip timezones
     def cmpStartTimeNoTZ(self, item):
         return self.cmpTimeAttribute(item, 'effectiveStartTime', False)

Modified: trunk/chandler/parcels/osaf/pim/calendar/tests/TestReminders.py (11435 => 11436)

--- trunk/chandler/parcels/osaf/pim/calendar/tests/TestReminders.py	2006-08-17 18:02:08 UTC (rev 11435)
+++ trunk/chandler/parcels/osaf/pim/calendar/tests/TestReminders.py	2006-08-17 18:54:38 UTC (rev 11436)
@@ -23,35 +23,52 @@
 
 class ReminderTestCase(TestDomainModel.DomainModelTestCase):
     def testReminders(self):
-        # Make an event and add a reminder to it.
+        # Make an event and add an expired absolute reminder to it.
         anEvent = CalendarEvent("calendarEventItem", itsView=self.rep.view,
                                 startTime=datetime(2005,3,8,12,00,
                                                    tzinfo = ICUtzinfo.default),
                                 duration=timedelta(hours=1),
                                 allDay=False, anyTime=False)
-        regularReminder = anEvent.makeReminder(timedelta(minutes=-10))
+        
+        absoluteReminderTime = datetime(2005,3,8,11,00, tzinfo=ICUtzinfo.default)
+        absoluteReminder = anEvent.setUserReminderTime(absoluteReminderTime)
+        
+        # Make sure it got connected right: one expired absolute reminder.
+        self.failIf(len(anEvent.reminders))
+        self.failUnless(len(anEvent.expiredReminders) == 1 \
+                        and anEvent.expiredReminders.first() is absoluteReminder)
+        self.failUnless(anEvent.userReminderTime == absoluteReminderTime)
+        self.failUnless(anEvent.userReminderInterval is None)
+        self.failUnless(anEvent.reminderFireTime == None)
+        
+        # Replace the absoluteReminder with a relative one
+        relativeReminderInterval = timedelta(minutes=-10)
+        relativeReminder = anEvent.setUserReminderInterval(relativeReminderInterval)
 
-        # Make sure it all got connected correctly
-        self.failUnless(len(anEvent.reminders) == 1 \
-                        and anEvent.reminders.first() is regularReminder)
-        self.failIf(len(anEvent.expiredReminders))
-        self.failUnless(anEvent.reminderFireTime == datetime(2005,3,8,11,50,
-                                 tzinfo = ICUtzinfo.default))
+        # Make sure it all got reconnected correctly: one expired relative reminder
+        self.failIf(len(anEvent.reminders))
+        self.failUnless(len(anEvent.expiredReminders) == 1 \
+                        and anEvent.expiredReminders.first() is relativeReminder)
+        self.failUnless(anEvent.userReminderInterval == relativeReminderInterval)
+        self.failUnless(anEvent.userReminderTime is None)
+        self.failUnless(anEvent.reminderFireTime == None)
 
         # Snooze the reminder for 5 minutes.
-        snoozeReminder = anEvent.snoozeReminder(regularReminder,
+        snoozeReminder = anEvent.snoozeReminder(relativeReminder,
                                                 timedelta(minutes=5))
-        # (should move the old reminder to expired)
-        self.failUnless(list(anEvent.expiredReminders) == [ regularReminder ])
+        # Check connections: the relative expired reminder remains, plus an
+        # active absolute reminder that we won't keep when it fires.
+        self.failUnless(list(anEvent.expiredReminders) == [ relativeReminder ])
         self.failUnless(list(anEvent.reminders) == [ snoozeReminder ])
-        self.failUnless(snoozeReminder.reminderItems.first() is not None)
+        self.failUnless(snoozeReminder.keepExpired == False)
+        self.failUnless(snoozeReminder.reminderItems.first() is anEvent)
 
         # Dismiss the snoozed reminder
         anEvent.dismissReminder(snoozeReminder)
         # (should destroy the snoozed reminder, leaving only the expired one)
         self.failIf(len(anEvent.reminders))
-        self.failUnless(list(anEvent.expiredReminders) == [ regularReminder ])
-        self.failUnless(regularReminder.reminderItems.first() is None)
+        self.failUnless(list(anEvent.expiredReminders) == [ relativeReminder ])
+        self.failUnless(relativeReminder.reminderItems.first() is None)
 
 if __name__ == "__main__":
     unittest.main()

Modified: trunk/chandler/parcels/osaf/pim/generate.py (11435 => 11436)

--- trunk/chandler/parcels/osaf/pim/generate.py	2006-08-17 18:02:08 UTC (rev 11435)
+++ trunk/chandler/parcels/osaf/pim/generate.py	2006-08-17 18:54:38 UTC (rev 11436)
@@ -78,7 +78,7 @@
     # Maybe a nice reminder?
     reminderInterval = random.choice(REMINDERS)
     if reminderInterval is not None:
-        event.makeReminder(timedelta(minutes=-reminderInterval))
+        event.userReminderInterval = timedelta(minutes=-reminderInterval)
         
     # Add a location to 2/3 of the events
     if random.randrange(3) > 0:
@@ -87,8 +87,6 @@
         else:
             event.location = Calendar.Location.getLocation(view, random.choice(LOCATIONS))
 
-
-
     event.importance = random.choice(pim.ImportanceEnum.values)
     event.triageStatus = random.choice(pim.TriageEnum.values)
     return event

Modified: trunk/chandler/parcels/osaf/pim/items.py (11435 => 11436)

--- trunk/chandler/parcels/osaf/pim/items.py	2006-08-17 18:02:08 UTC (rev 11435)
+++ trunk/chandler/parcels/osaf/pim/items.py	2006-08-17 18:54:38 UTC (rev 11436)
@@ -625,7 +625,32 @@
 
         return not isSharedInAnyReadOnlyShares
 
+    # For use in indexing time-related attributes. We only use this for 
+    # reminderFireTime here, but CalendarEventMixin uses this a lot more...
+    def cmpTimeAttribute(self, item, attr, useTZ=True):
+        """Compare item and self.attr, ignore timezones if useTZ is False."""
+        itemTime = getattr(item, attr, None)
+        selfTime = getattr(self, attr, None)
 
+        if itemTime is None:
+            if selfTime is None:
+                # both attributes are None, so item and self compare as equal
+                return 0
+            else:
+                return -1
+        elif not useTZ:
+            itemTime = itemTime.replace(tzinfo = None)
+
+        if selfTime is None:
+            return 1
+        elif not useTZ:
+            selfTime = selfTime.replace(tzinfo = None)
+
+        return cmp(selfTime, itemTime)
+
+    def cmpReminderTime(self, item):
+        return self.cmpTimeAttribute(item, 'reminderFireTime')
+
 """
 STAMPING SUPPORT CLASSES
 """

Modified: trunk/chandler/parcels/osaf/pim/reminders.py (11435 => 11436)

--- trunk/chandler/parcels/osaf/pim/reminders.py	2006-08-17 18:02:08 UTC (rev 11435)
+++ trunk/chandler/parcels/osaf/pim/reminders.py	2006-08-17 18:54:38 UTC (rev 11436)
@@ -18,18 +18,42 @@
 from datetime import datetime, time, timedelta
 from PyICU import ICUtzinfo
 
+# Make a value we can use for distant (or invalid) reminder times
+farFuture = datetime.max
+if getattr(farFuture, 'tzInfo', None) is None:
+    farFuture = farFuture.replace(tzinfo=ICUtzinfo.default)
 
 class Reminder(schema.Item):
-    delta = schema.One(
-        schema.TimeDelta,
-        doc="The amount in advance this reminder should occur (usually negative!)",
+    absoluteTime = schema.One(
+        schema.DateTimeTZ,
+        defaultValue=None,
+        doc="If set, overrides relativeTo as the base time for this reminder"
     )
 
     relativeTo = schema.One(
         schema.Text,
-        initialValue='effectiveStartTime',
+        defaultValue=None,
+        doc="The Remindable attribute that we're relative to",
     )
 
+    delta = schema.One(
+        schema.TimeDelta,
+        defaultValue=timedelta(0),
+        doc="Offset relative to 'relativeTo' that this reminder should occur",
+    )
+    
+    userCreated = schema.One(
+        schema.Boolean,
+        defaultValue=True,
+        doc="Is a user-created reminder?"
+    )
+        
+    keepExpired = schema.One(
+        schema.Boolean,
+        defaultValue=True,
+        doc="Should we keep this around (in the Remindable's expiredReminders) "
+            "after it fires?")
+    
     reminderItems = schema.Sequence(
         "Remindable",
         inverse="reminders",
@@ -42,28 +66,29 @@
         initialValue=[]
     )
 
-    snoozedUntil = schema.One(
-        schema.DateTimeTZ,
-        defaultValue=None
-    )
-
     schema.addClouds(
-        sharing = schema.Cloud(delta, relativeTo, snoozedUntil)
+        sharing = schema.Cloud(absoluteTime, delta, relativeTo, 
+                               userCreated, keepExpired)
     )
 
     def getBaseTimeFor(self, remindable):
         """
-        Get the relative-to time for this remindable's next reminder
-        so that the UI can generate a message relative to it.
+        Get the base time for this remindable's next reminder:
+        - it's our absolute time if we have one; 
+        - otherwise, get the relative-to time from our remindable
+        - otherwise, use a time in the far future.
         """
-        return getattr(remindable, self.relativeTo, datetime.max)
+        return self.absoluteTime or getattr(remindable, self.relativeTo) \
+               or farFuture
 
     def getNextReminderTimeFor(self, remindable):
         """ Get the time for this remindable's next reminder """
-        result = self.snoozedUntil or \
-               (self.getBaseTimeFor(remindable) + self.delta)
-        if result.tzinfo is None:
-            result = result.replace(tzinfo=ICUtzinfo.default)
+        result = self.getBaseTimeFor(remindable)
+        if result != farFuture:
+            result += self.delta
+        assert result.tzinfo is not None
+        #if result.tzinfo is None:
+            #result = result.replace(tzinfo=ICUtzinfo.default)
         return result
 
 class Remindable(schema.Item):
@@ -86,75 +111,107 @@
         )
     )
 
-    def getReminderInterval(self):
+    def getUserReminder(self, collectionToo=False):
         for attr in ("reminders", "expiredReminders"):
             if (self.hasLocalAttributeValue(attr)):
-                #@@@ This assumes we've only got 0 or 1 reminders.
-                first = getattr(self, attr).first()
-                try:
-                    return first.delta
-                except AttributeError:
-                    pass
+                collection = getattr(self, attr)
+                for reminder in collection:
+                    if reminder.userCreated:
+                        return collectionToo and (collection, reminder) or reminder
+        return collectionToo and (None, None) or None
 
-        return None
+    def replaceUserReminder(self, **kwds):
+        (collection, userReminder) = self.getUserReminder(True)
 
-    def setReminderInterval(self, delta):
-        reminderCollection = self.reminders
-        firstReminder = reminderCollection.first()
+        if userReminder is not None:
+            collection.remove(userReminder)
+            if not (len(userReminder.reminderItems) or \
+                    len(userReminder.expiredReminderItems)):
+                userReminder.delete()
 
-        if firstReminder is None:
-            reminderCollection = self.expiredReminders
-            firstReminder = reminderCollection.first()
+        if kwds.get('delta') is None and kwds.get('absoluteTime') is None:
+            return None
+        
+        return self.makeReminder(userCreated=True, keepExpired=True,
+                                 checkExpired=True, **kwds)
+    
+    # @@@ Note: 'Calculated' APIs are provided for both relative and absolute
+    # user-set reminders, even though only one reminder (which can be of either
+    # flavor) can be set right now. The 'set' functions can replace an existing
+    # reminder of either flavor, but the 'get' functions ignore (that is, return
+    # 'None' for) reminders of the wrong flavor.
+    
+    def getUserReminderInterval(self):
+        userReminder = self.getUserReminder()
+        if userReminder is None or userReminder.absoluteTime is not None:
+            return None
+        return userReminder.delta
 
-        if firstReminder is not None:
-            reminderCollection.remove(firstReminder)
-            if not (len(firstReminder.reminderItems) or \
-                    len(firstReminder.expiredReminderItems)):
-                firstReminder.delete()
+    def setUserReminderInterval(self, delta):
+        assert hasattr(self, 'effectiveStartTime')
+        return self.replaceUserReminder(delta=delta, relativeTo='effectiveStartTime')
 
-        if delta is not None:
-            self.makeReminder(delta, checkExpired=True)
-
-    reminderInterval = Calculated(
+    userReminderInterval = Calculated(
         schema.TimeDelta,
         basedOn=('reminders',),
-        fget=getReminderInterval,
-        fset=setReminderInterval,
-        doc="Reminder interval, computed from the first unexpired reminder."
+        fget=getUserReminderInterval,
+        fset=setUserReminderInterval,
+        doc="User-set reminder interval, computed from the first unexpired reminder."
     )
 
+    def getUserReminderTime(self):
+        userReminder = self.getUserReminder()
+        if userReminder is None or userReminder.absoluteTime is None:
+            return None
+        return userReminder.absoluteTime
+
+    def setUserReminderTime(self, absoluteTime):
+        return self.replaceUserReminder(absoluteTime=absoluteTime)
+    
+    userReminderTime = Calculated(
+        schema.DateTimeTZ,
+        basedOn=('reminders',),
+        fget=getUserReminderTime,
+        fset=setUserReminderTime,
+        doc="User-set absolute reminder time."
+    )
+
     def getReminderFireTime(self):
         """
-        A simplification of the possible complexity of reminder, assumes one
-        or zero reminders.  Returns a datetime or None.
+        Get the next reminder (of any kind) due to fire, or None if there aren't
+        any.
         """
-        reminder = self.reminders.first()
-        if reminder is None:
-            return None
-        else:
-            return reminder.getNextReminderTimeFor(self)
-
+        for reminder in self.reminders:
+            nextTime = reminder.getNextReminderTimeFor(self)
+            if nextTime is not None:
+                return nextTime
+        return None
+    
+    # @@@ For now, this is used to set absolute user reminders
+    # @@@ This is used for the next reminder of any kind (user or not), which is
+    # what the reminder-firing mechanism wants
     reminderFireTime = Calculated(
         schema.DateTimeTZ,
         basedOn=('startTime', 'allDay', 'anyTime', 'reminders'),
         fget=getReminderFireTime,
         doc="Reminder fire time, or None for no unexpired reminders")
 
-    def makeReminder(self, delta, checkExpired=False):
+    def makeReminder(self, checkExpired=False, **kwds):
         # @@@ I think the proxy code should override calls to this method
         # add a separate reference to this reminder to each generated event,
         # (or something like that). (Remindable.snoozeReminder will call this
         # method; that operation should only affect the actual event, not the
         # series)
-        newReminder = Reminder(None, delta=delta, itsView=self.itsView)
+        
+        newReminder = Reminder(None, itsView=self.itsView, **kwds)
 
         addThisTo = self.reminders
-
         if checkExpired:
             nextTime = newReminder.getNextReminderTimeFor(self)
 
             if (nextTime is not None and
                 nextTime < datetime.now(ICUtzinfo.default)):
+                assert kwds['keepExpired'], "Creating an expired reminder that isn't marked 'keepExpired'?"
                 addThisTo = self.expiredReminders
 
         addThisTo.add(newReminder)
@@ -166,8 +223,6 @@
         # Make sure the next one's around, so we'll prime the reminder-
         # watching mechanism to alert us about it. We also check that
         # reminders for past events don't trigger this one.
-        now = datetime.now(ICUtzinfo.default)
-
         try:
             getNextOccurrenceMethod = self.getNextOccurrence
         except AttributeError:
@@ -177,15 +232,15 @@
             # don't need to do anything with it; we just
             # want to make sure it's been instantiated
             # so that the next reminder will fire.
-            getNextOccurrenceMethod(after=now)
+            getNextOccurrenceMethod(after=datetime.now(ICUtzinfo.default))
 
         # In the case of generated occurrences, the reminder
         # may already have fired (cf fixReminders() in
         # CalendarEventMixin.getNextOccurrence
         if reminder in self.reminders:
             self.reminders.remove(reminder)
-        if getattr(reminder, 'snoozedUntil', None) is not None:
-            # This is a "snooze" reminder, just toss it.
+        if not reminder.keepExpired:
+            # This is a system or "snooze" reminder, just toss it.
             assert len(reminder.reminderItems) == 0
             assert len(reminder.expiredReminderItems) == 0
             reminder.delete()
@@ -194,7 +249,6 @@
                 self.expiredReminders.add(reminder)
 
 
-
     def snoozeReminder(self, reminder, delay):
         """ Snooze this reminder for this long. """
         # Dismiss the original reminder
@@ -203,7 +257,9 @@
 
         # Make a new reminder for this event
         newReminder = Reminder(None, itsView=self.itsView,
-                               snoozedUntil=(datetime.now(ICUtzinfo.default) +
-                                             delay))
+                               absoluteTime=(datetime.now(ICUtzinfo.default) +
+                                             delay),
+                               keepExpired=False,
+                               userCreated=False)
         self.reminders.add(newReminder)
         return newReminder

Modified: trunk/chandler/parcels/osaf/sharing/ICalendar.py (11435 => 11436)

--- trunk/chandler/parcels/osaf/sharing/ICalendar.py	2006-08-17 18:02:08 UTC (rev 11435)
+++ trunk/chandler/parcels/osaf/sharing/ICalendar.py	2006-08-17 18:54:38 UTC (rev 11436)
@@ -142,9 +142,15 @@
             pass
 
         if not filters or "reminders" not in filters:
-            firstReminder = item.reminders.first() or item.expiredReminders.first()
+            firstReminder = item.getUserReminder()
             if firstReminder is not None:
-                comp.add('valarm').add('trigger').value = firstReminder.delta
+                if firstReminder.absoluteTime is not None:
+                    value = firstReminder.absoluteTime
+                else:
+                    # @@@ For now, all relative reminders are relative to starttime
+                    assert firstReminder.relativeTo == 'effectiveStartTime'
+                    value = firstReminder.delta
+                comp.add('valarm').add('trigger').value = value
         
         if item.getAttributeValue('modificationFor', default=None) is not None:
             recurrenceid = comp.add('recurrence-id')
@@ -434,13 +440,18 @@
                 # dtstart.
                 anyTime = getattr(event.dtstart, 'x_osaf_anytime_param', None) == 'TRUE'
 
+                reminderDelta = None
+                reminderAbsoluteTime = None
                 try:
-                    reminderDelta = event.valarm.trigger.value
-                    if type(reminderDelta) is datetime.datetime:
-                        reminderDelta = reminderDelta - dtstart
+                    reminderValue = event.valarm.trigger.value
                 except AttributeError:
-                    reminderDelta = None
-
+                    pass
+                else:
+                    if type(reminderValue) is datetime.datetime:
+                        reminderAbsolute = reminderValue
+                    else:
+                        assert type(reminderValue) is datetime.timedelta
+                        reminderDelta = reminderValue
                 
                 if duration is None:
                     if dtend is not None:
@@ -577,11 +588,15 @@
                     change('location', Calendar.Location.getLocation(view,
                                                                      location))
                     
-                # rruleset and reminderInterval need to be set last
+                # rruleset and userReminderInterval/userReminderTime must be set last
                 changeLast = []
                 if not filters or "reminders" not in filters:
                     if reminderDelta is not None:
-                        changeLast.append(('reminderInterval', reminderDelta))
+                        changeLast.append(('userReminderInterval', 
+                                           reminderDelta))
+                    elif reminderAbsoluteTime is None:
+                        changeLast.append(('userReminderTime', 
+                                           reminderAbsoluteTime))
                 
                 rruleset = event.rruleset
                 if rruleset is not None:

Modified: trunk/chandler/parcels/osaf/views/detail/detail.py (11435 => 11436)

--- trunk/chandler/parcels/osaf/views/detail/detail.py	2006-08-17 18:02:08 UTC (rev 11435)
+++ trunk/chandler/parcels/osaf/views/detail/detail.py	2006-08-17 18:54:38 UTC (rev 11436)
@@ -746,7 +746,7 @@
         """
         Get the value from the specified attribute of the item.
         """
-        return item.reminderInterval
+        return item.userReminderInterval
 
     def SetAttributeValue (self, item, attributeName, value):
         """Set the value of the attribute given by the value.

Modified: trunk/chandler/parcels/osaf/views/detail/detailblocks.py (11435 => 11436)

--- trunk/chandler/parcels/osaf/views/detail/detailblocks.py	2006-08-17 18:02:08 UTC (rev 11435)
+++ trunk/chandler/parcels/osaf/views/detail/detailblocks.py	2006-08-17 18:54:38 UTC (rev 11436)
@@ -405,7 +405,7 @@
                 makeLabel(parcel, _(u'alarm'), borderTop=5),
                 makeSpacer(parcel, width=8),
                 makeEditor(parcel, 'EditReminder',
-                    viewAttribute=u'reminderInterval',
+                    viewAttribute=u'userReminderInterval',
                     presentationStyle={
                         # @@@ XXX i18n: the code assumes that if the value
                         # starts with a digit, it's a number of minutes; if not,

Modified: trunk/chandler/util/GenerateItemsFromFile.py (11435 => 11436)

--- trunk/chandler/util/GenerateItemsFromFile.py	2006-08-17 18:02:08 UTC (rev 11435)
+++ trunk/chandler/util/GenerateItemsFromFile.py	2006-08-17 18:54:38 UTC (rev 11436)
@@ -185,7 +185,7 @@
             reminderInterval = random.choice(REMINDERS)
         else:
             reminderInterval = string.atoi(args[7])
-        event.makeReminder(timedelta(minutes=-reminderInterval))
+        event.userReminderInterval = timedelta(minutes=-reminderInterval)
 
     #location
     if args[8]=='*': # semi-random data




_______________________________________________
Commits mailing list
[email protected]
http://lists.osafoundation.org/mailman/listinfo/commits

Reply via email to