source: trunk/Cocoa/Pester/Source/PSAlarm.m@ 602

Last change on this file since 602 was 602, checked in by Nicholas Riley, 14 years ago

Rename variables which shadow stdlib functions (and maxSize).

File size: 20.1 KB
RevLine 
[24]1//
2// PSAlarm.m
3// Pester
4//
5// Created by Nicholas Riley on Wed Oct 09 2002.
6// Copyright (c) 2002 Nicholas Riley. All rights reserved.
7//
8
9#import "PSAlarm.h"
[34]10#import "PSAlert.h"
[53]11#import "PSAlerts.h"
[61]12#import "PSTimer.h"
[53]13#import "NSCalendarDate-NJRExtensions.h"
14#import "NSDictionary-NJRExtensions.h"
15#import "NSString-NJRExtensions.h"
[24]16
[26]17NSString * const PSAlarmTimerSetNotification = @"PSAlarmTimerSetNotification";
18NSString * const PSAlarmTimerExpiredNotification = @"PSAlarmTimerExpiredNotification";
[53]19NSString * const PSAlarmDiedNotification = @"PSAlarmDiedNotification";
[24]20
[53]21// property list keys
22static NSString * const PLAlarmType = @"type"; // NSString
23static NSString * const PLAlarmDate = @"date"; // NSNumber
24static NSString * const PLAlarmInterval = @"interval"; // NSNumber
25static NSString * const PLAlarmSnoozeInterval = @"snooze interval"; // NSNumber
26static NSString * const PLAlarmMessage = @"message"; // NSString
27static NSString * const PLAlarmAlerts = @"alerts"; // NSDictionary
28static NSString * const PLAlarmRepeating = @"repeating"; // NSNumber
29
[358]30static NSDateFormatter *dateFormatter, *shortDateFormatter, *timeFormatter;
[43]31
[24]32@implementation PSAlarm
33
[51]34#pragma mark initialize-release
35
[358]36+ (void)initialize;
[43]37{
[358]38 [NSDateFormatter setDefaultFormatterBehavior: NSDateFormatterBehavior10_4];
39 dateFormatter = [[NSDateFormatter alloc] init];
40 [dateFormatter setTimeStyle: NSDateFormatterNoStyle];
41 [dateFormatter setDateStyle: NSDateFormatterFullStyle];
42 shortDateFormatter = [[NSDateFormatter alloc] init];
43 [shortDateFormatter setTimeStyle: NSDateFormatterNoStyle];
44 [shortDateFormatter setDateStyle: NSDateFormatterShortStyle];
45 timeFormatter = [[NSDateFormatter alloc] init];
46 [timeFormatter setTimeStyle: NSDateFormatterMediumStyle];
47 [timeFormatter setDateStyle: NSDateFormatterNoStyle];
[43]48}
49
[26]50- (void)dealloc;
51{
52 // NSLog(@"DEALLOC %@", self);
53 alarmType = PSAlarmInvalid;
54 [alarmDate release]; alarmDate = nil;
55 [alarmMessage release]; alarmMessage = nil;
56 [invalidMessage release]; invalidMessage = nil;
[28]57 [timer invalidate]; [timer release]; timer = nil;
[34]58 [alerts release]; alerts = nil;
[26]59 [super dealloc];
60}
61
[51]62#pragma mark private
63
[24]64- (void)_setAlarmDate:(NSCalendarDate *)aDate;
65{
66 if (alarmDate != aDate) {
67 [alarmDate release];
68 alarmDate = nil;
69 alarmDate = [aDate retain];
70 }
71}
72
[51]73- (void)_beInvalid:(NSString *)aMessage;
[24]74{
75 alarmType = PSAlarmInvalid;
76 if (aMessage != invalidMessage) {
77 [invalidMessage release];
78 invalidMessage = nil;
79 [self _setAlarmDate: nil];
80 alarmInterval = 0;
81 invalidMessage = [aMessage retain];
82 }
83}
84
[51]85- (void)_beValidWithType:(PSAlarmType)type;
[24]86{
[28]87 if (alarmType == PSAlarmSet) return; // already valid
[24]88 [invalidMessage release];
89 invalidMessage = nil;
90 alarmType = type;
[53]91 if (type != PSAlarmInterval) [self setRepeating: NO];
[24]92}
93
94- (void)_setDateFromInterval;
95{
[53]96 [self _setAlarmDate: [NSCalendarDate dateWithTimeIntervalSinceNow: alarmInterval]];
[51]97 [self _beValidWithType: PSAlarmInterval];
[24]98}
99
[51]100- (void)_setIntervalFromDate;
[24]101{
[53]102 alarmInterval = [alarmDate timeIntervalSinceNow];
[24]103 if (alarmInterval <= 0) {
[51]104 [self _beInvalid: @"Please specify an alarm time in the future."];
105 return;
[24]106 }
[51]107 [self _beValidWithType: PSAlarmDate];
[24]108}
109
[53]110- (PSAlarmType)_alarmTypeForString:(NSString *)string;
111{
112 if ([string isEqualToString: @"PSAlarmDate"]) return PSAlarmDate;
113 if ([string isEqualToString: @"PSAlarmInterval"]) return PSAlarmInterval;
114 if ([string isEqualToString: @"PSAlarmSet"]) return PSAlarmSet;
115 if ([string isEqualToString: @"PSAlarmInvalid"]) return PSAlarmInvalid;
116 if ([string isEqualToString: @"PSAlarmSnooze"]) return PSAlarmSnooze;
117 if ([string isEqualToString: @"PSAlarmExpired"]) return PSAlarmExpired;
[587]118 return PSAlarmInvalid;
[53]119}
120
[51]121- (NSString *)_alarmTypeString;
[24]122{
[51]123 switch (alarmType) {
124 case PSAlarmDate: return @"PSAlarmDate";
125 case PSAlarmInterval: return @"PSAlarmInterval";
126 case PSAlarmSet: return @"PSAlarmSet";
127 case PSAlarmInvalid: return @"PSAlarmInvalid";
[53]128 case PSAlarmSnooze: return @"PSAlarmSnooze";
129 case PSAlarmExpired: return @"PSAlarmExpired";
[51]130 default: return [NSString stringWithFormat: @"<unknown: %u>", alarmType];
131 }
132}
133
[53]134- (NSString *)_stringForInterval:(unsigned long long)interval;
135{
136 const unsigned long long minute = 60, hour = minute * 60, day = hour * 24, year = day * 365.26;
137 // +[NSString stringWithFormat:] in 10.1 does not support long longs: work around it by converting to unsigned ints or longs for display
138 if (interval == 0) return nil;
139 if (interval < minute) return [NSString stringWithFormat: @"%us", (unsigned)interval];
[113]140 if (interval < hour) return [NSString stringWithFormat: @"%um", (unsigned)(interval / minute)];
[53]141 if (interval < day) return [NSString stringWithFormat: @"%uh %um", (unsigned)(interval / hour), (unsigned)((interval % hour) / minute)];
142 if (interval < 2 * day) return @"One day";
143 if (interval < year) return [NSString stringWithFormat: @"%u days", (unsigned)(interval / day)];
144 if (interval < 2 * year) return @"One year";
145 return [NSString stringWithFormat: @"%lu years", (unsigned long)(interval / year)];
146}
147
[61]148- (void)_timerExpired:(PSTimer *)aTimer;
[51]149{
[53]150 NSLog(@"expired: %@; now %@", [[aTimer fireDate] description], [[NSDate date] description]);
151 alarmType = PSAlarmExpired;
[51]152 [[NSNotificationCenter defaultCenter] postNotificationName: PSAlarmTimerExpiredNotification object: self];
153 [timer release]; timer = nil;
154}
155
156#pragma mark alarm setting
157
158- (void)setInterval:(NSTimeInterval)anInterval;
159{
160 alarmInterval = anInterval;
[24]161 if (alarmInterval <= 0) {
[51]162 [self _beInvalid: @"Please specify an alarm interval."]; return;
[24]163 }
[51]164 [self _setDateFromInterval];
[24]165}
166
[26]167- (void)setForDateAtTime:(NSCalendarDate *)dateTime;
[24]168{
[26]169 [self _setAlarmDate: dateTime];
[24]170 [self _setIntervalFromDate];
171}
172
[602]173- (void)setForDate:(NSDate *)aDate atTime:(NSDate *)aTime;
[24]174{
[53]175 NSCalendarDate *dateTime;
[602]176 if (aTime == nil && aDate == nil) {
[51]177 [self _beInvalid: @"Please specify an alarm date and time."]; return;
[24]178 }
[602]179 if (aTime == nil) {
[51]180 [self _beInvalid: @"Please specify an alarm time."]; return;
[24]181 }
[602]182 if (aDate == nil) {
[51]183 [self _beInvalid: @"Please specify an alarm date."]; return;
[24]184 }
185 // XXX if calTime's date is different from the default date, complain
[602]186 dateTime = [NSCalendarDate dateWithDate: aDate atTime: aTime];
[53]187 if (dateTime == nil) {
[105]188 [self _beInvalid: @"Please specify a reasonable date and time."]; return;
[24]189 }
[53]190 [self setForDateAtTime: dateTime];
[24]191}
192
[53]193- (void)setRepeating:(BOOL)isRepeating;
194{
195 repeating = isRepeating;
196}
197
198- (void)setSnoozeInterval:(NSTimeInterval)anInterval;
199{
200 snoozeInterval = anInterval;
[103]201 NSAssert(alarmType == PSAlarmExpired, NSLocalizedString(@"Can't snooze an alarm that hasn't expired", "Assertion for PSAlarm snooze setting"));
[53]202 alarmType = PSAlarmSnooze;
203}
204
[61]205- (void)setWakeUp:(BOOL)doWake;
206{
207 [timer setWakeUp: doWake];
208}
209
[51]210#pragma mark accessing
211
212- (NSString *)message;
[24]213{
[51]214 if (alarmMessage == nil || [alarmMessage isEqualToString: @""])
215 return @"Alarm!";
216 return alarmMessage;
[24]217}
218
219- (void)setMessage:(NSString *)aMessage;
220{
221 if (aMessage != alarmMessage) {
222 [alarmMessage release];
223 alarmMessage = nil;
224 alarmMessage = [aMessage retain];
225 }
226}
227
[51]228- (BOOL)isValid;
[24]229{
[51]230 if (alarmType == PSAlarmDate) [self _setIntervalFromDate];
[53]231 if (alarmType == PSAlarmInvalid ||
232 (alarmType == PSAlarmExpired && ![self isRepeating])) return NO;
233 return YES;
[24]234}
235
236- (NSString *)invalidMessage;
237{
[26]238 if (invalidMessage == nil) return @"";
[24]239 return invalidMessage;
240}
241
[28]242- (NSCalendarDate *)date;
[24]243{
244 if (alarmType == PSAlarmInterval) [self _setDateFromInterval];
245 return alarmDate;
246}
247
[366]248- (NSDate *)time;
[51]249{
[366]250 // XXX this works, but the result is unlikely to be useful until we move away from NSCalendarDate elsewhere
[51]251 if (alarmType == PSAlarmInterval) [self _setDateFromInterval];
[366]252
253 NSCalendar *calendar = [NSCalendar currentCalendar];
254
255 return [calendar dateFromComponents:
256 [calendar components: NSHourCalendarUnit|NSMinuteCalendarUnit|NSSecondCalendarUnit fromDate: alarmDate]];
[51]257}
258
259- (NSTimeInterval)interval;
260{
[53]261 if (alarmType == PSAlarmDate) [self _setIntervalFromDate];
[51]262 return alarmInterval;
263}
264
[53]265- (NSTimeInterval)snoozeInterval;
[51]266{
[53]267 return snoozeInterval;
[51]268}
269
[53]270- (NSTimeInterval)timeRemaining;
[51]271{
[103]272 NSAssert1(alarmType == PSAlarmSet, NSLocalizedString(@"Can't get time remaining on alarm with no timer set: %@", "Assertion for PSAlarm time remaining, internal error; %@ replaced by alarm description"), self);
[53]273 return -[[NSDate date] timeIntervalSinceDate: alarmDate];
[51]274}
275
[53]276- (void)setAlerts:(PSAlerts *)theAlerts;
[51]277{
[53]278 [alerts release]; alerts = nil;
279 alerts = [theAlerts retain];
[51]280}
281
[53]282- (PSAlerts *)alerts;
283{
284 if (alerts == nil) alerts = [[PSAlerts alloc] init];
285 return alerts;
286}
287
288- (BOOL)isRepeating;
289{
290 return repeating;
291}
292
[43]293- (NSString *)dateString;
294{
[358]295 return [dateFormatter stringFromDate: [self date]];
[43]296}
297
[28]298- (NSString *)shortDateString;
299{
[358]300 return [shortDateFormatter stringFromDate: [self date]];
[28]301}
302
303- (NSString *)timeString;
304{
[358]305 return [timeFormatter stringFromDate: [self date]];
[28]306}
307
[53]308- (NSString *)dateTimeString;
[28]309{
[53]310 return [NSString stringWithFormat: @"%@ at %@", [self dateString], [self timeString]];
311}
312
313- (NSString *)nextDateTimeString;
314{
315 if (![self isRepeating]) {
316 return nil;
317 } else {
318 NSCalendarDate *date = [[NSCalendarDate alloc] initWithTimeIntervalSinceNow: [self interval]];
319 NSString *nextDateTimeString = [NSString stringWithFormat: @"%@ at %@",
[358]320 [dateFormatter stringFromDate: date],
321 [timeFormatter stringFromDate: date]];
[53]322 [date release];
323 return nextDateTimeString;
324 }
325}
326
327- (NSString *)intervalString;
328{
[551]329 const unsigned long long mval = 999, minute = 60, hour = minute * 60, day = hour * 24, week = day * 7;
[28]330 unsigned long long interval = [self interval];
[53]331 if (interval == 0) return nil;
[551]332
[53]333 if (interval == 1) return @"One second";
334 if (interval == minute) return @"One minute";
[551]335 if (interval == hour) return @"One hour";
336 if (interval == day) return @"One day";
337 if (interval == week) return @"One week";
338
339 if (interval % week == 0) return [NSString stringWithFormat: @"%u weeks", (unsigned)(interval / week)];
340 if (interval % day == 0) return [NSString stringWithFormat: @"%u days", (unsigned)(interval / day)];
341 if (interval % hour == 0) return [NSString stringWithFormat: @"%u hours", (unsigned)(interval / hour)];
[53]342 if (interval % minute == 0) return [NSString stringWithFormat: @"%u minutes", (unsigned)(interval / minute)];
[551]343
[53]344 if (interval <= mval) return [NSString stringWithFormat: @"%u seconds", (unsigned)interval];
345 if (interval <= mval * minute) return [NSString stringWithFormat: @"%u minutes", (unsigned)(interval / minute)];
346 if (interval <= mval * hour) return [NSString stringWithFormat: @"%u hours", (unsigned)(interval / hour)];
[551]347 if (interval <= mval * day) return [NSString stringWithFormat: @"%u days", (unsigned)(interval / day)];
348 return [NSString stringWithFormat: @"%u weeks", (unsigned)(interval / week)];
349
[53]350 return [self _stringForInterval: interval];
[28]351}
352
[53]353- (NSString *)timeRemainingString;
354{
355 NSString *timeRemainingString = [self _stringForInterval: llround([self timeRemaining])];
356
[355]357 if (timeRemainingString == nil) return @"«expired»";
[53]358 return timeRemainingString;
359}
360
361- (NSAttributedString *)prettyDescription;
362{
363 NSMutableAttributedString *string = [[NSMutableAttributedString alloc] init];
364 NSAttributedString *alertList = [alerts prettyList];
365
366 [string appendAttributedString:
[364]367 [[NSString stringWithFormat: NSLocalizedString(@"At alarm time for '%@':\n", "Alert list title in pretty description, %@ replaced with message"), [self message]] small]];
[53]368 if (alertList != nil) {
369 [string appendAttributedString: alertList];
370 } else {
371 [string appendAttributedString: [@"Do nothing." small]];
372 }
373 if ([self isRepeating]) {
374 [string appendAttributedString:
375 [[NSString stringWithFormat: @"\nAlarm repeats every %@.", [[self intervalString] lowercaseString]] small]];
376 }
377 return [string autorelease];
378}
379
[51]380#pragma mark actions
[24]381
[26]382- (BOOL)setTimer;
383{
[53]384 if (alarmType == PSAlarmExpired) {
385 if ([self isRepeating]) {
386 [self _setDateFromInterval];
387 } else {
388 [[NSNotificationCenter defaultCenter] postNotificationName: PSAlarmDiedNotification object: self];
[26]389 return NO;
[53]390 }
391 } else if (alarmType == PSAlarmDate) {
392 if (![self isValid]) return NO;
393 } else if (alarmType == PSAlarmSnooze) {
394 [self _setAlarmDate: [NSCalendarDate dateWithTimeIntervalSinceNow: snoozeInterval]];
395 } else if (alarmType != PSAlarmInterval) {
396 return NO;
[26]397 }
[61]398 timer = [PSTimer scheduledTimerWithTimeInterval: (alarmType == PSAlarmSnooze ? snoozeInterval : alarmInterval) target: self selector: @selector(_timerExpired:) userInfo: nil repeats: NO];
[53]399 if (timer == nil) return NO;
400 [timer retain];
401 alarmType = PSAlarmSet;
[61]402 [alerts prepareForAlarm: self];
403
[53]404 [[NSNotificationCenter defaultCenter] postNotificationName: PSAlarmTimerSetNotification object: self];
405 // NSLog(@"set: %@; now %@; remaining %@", [[timer fireDate] description], [[NSDate date] description], [self timeRemainingString]);
406 return YES;
[26]407}
408
[51]409- (void)cancelTimer;
[26]410{
[28]411 [timer invalidate]; [timer release]; timer = nil;
[26]412}
413
[113]414- (void)resetTimer;
415{
416 if (timer != nil || alarmType != PSAlarmSet)
417 return;
418
419 alarmType = PSAlarmDate;
420 if (![self isRepeating]) {
421 [self setTimer];
422 } else {
423 // don't want to put this logic in setTimer or isValid because it can cause invalid alarms to be set (consider when someone clicks the "repeat" checkbox, then switches to a [nonrepeating, by design] date alarm, and enters a date that has passed: we do -not- want the alarm to magically morph into a repeating interval alarm)
424 NSTimeInterval savedInterval = alarmInterval;
[364]425 if ([self setTimer]) {
426 // alarm is set, but not repeating - and the interval is wrong because it was computed from the date
427 alarmInterval = savedInterval;
428 [self setRepeating: YES];
429 } else {
430 // alarm is now invalid: expired in the past, so we start the timer over again
431 // We could potentially start counting from the expiration date (or expiration date + n * interval), but this doesn't match our existing behavior.
[113]432 alarmType = PSAlarmInterval;
433 [self setInterval: savedInterval];
434 [self setTimer];
435 }
436 }
437}
438
[51]439#pragma mark comparing
[26]440
[51]441- (NSComparisonResult)compareDate:(PSAlarm *)otherAlarm;
[26]442{
443 return [[self date] compare: [otherAlarm date]];
444}
445
[51]446- (NSComparisonResult)compareMessage:(PSAlarm *)otherAlarm;
[34]447{
[51]448 return [[self message] caseInsensitiveCompare: [otherAlarm message]];
[34]449}
450
[51]451#pragma mark printing
[34]452
[26]453- (NSString *)description;
454{
[105]455 return [NSString stringWithFormat: @"%@: type %@ date %@ interval %.1f%@%@",
[26]456 [super description], [self _alarmTypeString], alarmDate, alarmInterval,
[105]457 (repeating ? @" repeating" : @""),
[26]458 (alarmType == PSAlarmInvalid ?
459 [NSString stringWithFormat: @"\ninvalid message: %@", invalidMessage]
460 : (alarmType == PSAlarmSet ?
461 [NSString stringWithFormat: @"\ntimer: %@", timer] : @""))];
462}
463
[53]464#pragma mark property list serialization (Pester 1.1)
[51]465
[53]466- (NSDictionary *)propertyListRepresentation;
467{
468 NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithCapacity: 5];
469 if (![self isValid]) return nil;
470 [dict setObject: [self _alarmTypeString] forKey: PLAlarmType];
471 switch (alarmType) {
472 case PSAlarmDate:
473 case PSAlarmSet:
474 [dict setObject: [NSNumber numberWithDouble: [alarmDate timeIntervalSinceReferenceDate]] forKey: PLAlarmDate];
475 case PSAlarmSnooze:
476 case PSAlarmInterval:
477 case PSAlarmExpired:
478 break;
479 default:
[103]480 NSAssert1(NO, NSLocalizedString(@"Can't save alarm type %@", "Assertion for invalid PSAlarm type on string; %@ replaced with alarm type string"), [self _alarmTypeString]);
[53]481 break;
482 }
[105]483 if ((alarmType != PSAlarmSet || repeating) && alarmType != PSAlarmDate) {
484 [dict setObject: [NSNumber numberWithBool: repeating] forKey: PLAlarmRepeating];
485 [dict setObject: [NSNumber numberWithDouble: alarmInterval] forKey: PLAlarmInterval];
486 }
[53]487 if (snoozeInterval != 0)
488 [dict setObject: [NSNumber numberWithDouble: snoozeInterval] forKey: PLAlarmSnoozeInterval];
489 [dict setObject: alarmMessage forKey: PLAlarmMessage];
490 if (alerts != nil) {
491 [dict setObject: [alerts propertyListRepresentation] forKey: PLAlarmAlerts];
492 }
493 return dict;
494}
495
496- (id)initWithPropertyList:(NSDictionary *)dict;
497{
498 if ( (self = [self init]) != nil) {
499 PSAlerts *alarmAlerts;
500 alarmType = [self _alarmTypeForString: [dict objectForRequiredKey: PLAlarmType]];
501 switch (alarmType) {
502 case PSAlarmDate:
503 case PSAlarmSet:
504 { NSCalendarDate *date = [[NSCalendarDate alloc] initWithTimeIntervalSinceReferenceDate: [[dict objectForRequiredKey: PLAlarmDate] doubleValue]];
505 [self _setAlarmDate: date];
506 [date release];
507 }
508 break;
509 case PSAlarmSnooze: // snooze interval set but not confirmed; ignore
510 alarmType = PSAlarmExpired;
511 case PSAlarmInterval:
512 case PSAlarmExpired:
513 break;
514 default:
[103]515 NSAssert1(NO, NSLocalizedString(@"Can't load alarm type %@", "Assertion for invalid PSAlarm type on load; %@ replaced with alarm type string"), [self _alarmTypeString]);
[53]516 break;
517 }
[105]518 repeating = [[dict objectForKey: PLAlarmRepeating] boolValue];
519 if ((alarmType != PSAlarmSet || repeating) && alarmType != PSAlarmDate)
520 alarmInterval = [[dict objectForRequiredKey: PLAlarmInterval] doubleValue];
[53]521 snoozeInterval = [[dict objectForKey: PLAlarmSnoozeInterval] doubleValue];
522 [self setMessage: [dict objectForRequiredKey: PLAlarmMessage]];
523 alarmAlerts = [[PSAlerts alloc] initWithPropertyList: [dict objectForRequiredKey: PLAlarmAlerts]];
524 [self setAlerts: alarmAlerts];
525 [alarmAlerts release];
[113]526 [self resetTimer];
[53]527 if (alarmType == PSAlarmExpired) {
528 [self setTimer];
529 if (alarmType == PSAlarmExpired) { // failed to restart
530 [self release];
531 self = nil;
532 }
533 }
534 }
535 return self;
536}
537
538#pragma mark archiving (Pester 1.0)
539
[26]540- (void)encodeWithCoder:(NSCoder *)coder;
541{
542 if (![self isValid]) return;
543 [coder encodeValueOfObjCType: @encode(PSAlarmType) at: &alarmType];
544 switch (alarmType) {
545 case PSAlarmDate:
546 case PSAlarmSet:
547 [coder encodeObject: alarmDate];
548 break;
549 case PSAlarmInterval:
550 [coder encodeValueOfObjCType: @encode(NSTimeInterval) at: &alarmInterval];
551 break;
552 default:
553 break;
554 }
555 [coder encodeObject: alarmMessage];
[28]556 // NSLog(@"encoded: %@", self); // XXX happening twice, gdb refuses to show proper backtrace, grr
[26]557 return;
558}
559
560- (id)initWithCoder:(NSCoder *)coder;
561{
[53]562 if ( (self = [self init]) != nil) {
563 PSAlerts *legacyAlerts = [[PSAlerts alloc] initWithPesterVersion1Alerts];
564 [self setAlerts: legacyAlerts];
565 [legacyAlerts release];
[26]566 [coder decodeValueOfObjCType: @encode(PSAlarmType) at: &alarmType];
567 switch (alarmType) {
568 case PSAlarmDate:
569 case PSAlarmSet:
570 [self _setAlarmDate: [coder decodeObject]];
571 break;
572 case PSAlarmInterval:
573 [coder decodeValueOfObjCType: @encode(NSTimeInterval) at: &alarmInterval];
574 break;
575 default:
576 break;
577 }
578 [self setMessage: [coder decodeObject]];
[364]579 if (alarmType == PSAlarmSet)
[26]580 alarmType = PSAlarmDate;
[364]581 // Note: the timer is not set here, so these alarms are inert.
582 // This helps make importing atomic (see -[PSAlarms importVersion1Alarms])
[26]583 }
584 return self;
585}
586
[24]587@end
Note: See TracBrowser for help on using the repository browser.