diff --git a/ActiveSync/iCalEvent+ActiveSync.m b/ActiveSync/iCalEvent+ActiveSync.m index 0a8ea7a56..bbffb0292 100644 --- a/ActiveSync/iCalEvent+ActiveSync.m +++ b/ActiveSync/iCalEvent+ActiveSync.m @@ -236,7 +236,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. { iCalAlarm *alarm; - alarm = [[self alarms] objectAtIndex: 0]; + alarm = [self firstDisplayOrAudioAlarm]; [s appendString: [alarm activeSyncRepresentationInContext: context]]; } diff --git a/SoObjects/Appointments/SOGoAppointmentFolder.m b/SoObjects/Appointments/SOGoAppointmentFolder.m index 19bc54630..792586330 100644 --- a/SoObjects/Appointments/SOGoAppointmentFolder.m +++ b/SoObjects/Appointments/SOGoAppointmentFolder.m @@ -981,7 +981,7 @@ static Class iCalEventK = nil; // alarm defined. if ([[component alarms] count]) { - alarm = [[component alarms] objectAtIndex: 0]; + alarm = [component firstDisplayOrAudioAlarm]; [row setObject: [NSNumber numberWithInt: [[alarm nextAlarmDate] timeIntervalSince1970]] forKey: @"c_nextalarm"]; } diff --git a/SoObjects/Appointments/iCalEntityObject+SOGo.h b/SoObjects/Appointments/iCalEntityObject+SOGo.h index abe9e8e43..56e982137 100644 --- a/SoObjects/Appointments/iCalEntityObject+SOGo.h +++ b/SoObjects/Appointments/iCalEntityObject+SOGo.h @@ -23,6 +23,7 @@ #import +@class iCalAlarm; @class NSMutableDictionary; @class SOGoUser; @@ -55,6 +56,9 @@ extern NSNumber *iCalDistantFutureNumber; - (NSMutableDictionary *) quickRecordFromContent: (NSString *) theContent container: (id) theContainer; +- (iCalAlarm *) firstSupportedAlarm; +- (iCalAlarm *) firstDisplayOrAudioAlarm; + - (void) updateNextAlarmDateInRow: (NSMutableDictionary *) row forContainer: (id) theContainer; diff --git a/SoObjects/Appointments/iCalEntityObject+SOGo.m b/SoObjects/Appointments/iCalEntityObject+SOGo.m index e0952cb58..48ba026c3 100644 --- a/SoObjects/Appointments/iCalEntityObject+SOGo.m +++ b/SoObjects/Appointments/iCalEntityObject+SOGo.m @@ -264,6 +264,50 @@ NSNumber *iCalDistantFutureNumber = nil; return created_by; } +// +// We ignore ACTION:PROCEDURE for now. +// +- (iCalAlarm *) firstSupportedAlarm +{ + iCalAlarm *anAlarm; + NSArray *alarms; + int i; + + alarms = [self alarms]; + + for (i = 0; i < [alarms count]; i++) + { + anAlarm = [[self alarms] objectAtIndex: i]; + + if ([[anAlarm action] caseInsensitiveCompare: @"DISPLAY"] == NSOrderedSame || + [[anAlarm action] caseInsensitiveCompare: @"AUDIO"] == NSOrderedSame || + [[anAlarm action] caseInsensitiveCompare: @"EMAIL"] == NSOrderedSame) + return anAlarm; + } + + return nil; +} + +- (iCalAlarm *) firstDisplayOrAudioAlarm +{ + iCalAlarm *anAlarm; + NSArray *alarms; + int i; + + alarms = [self alarms]; + + for (i = 0; i < [alarms count]; i++) + { + anAlarm = [[self alarms] objectAtIndex: i]; + + if ([[anAlarm action] caseInsensitiveCompare: @"DISPLAY"] == NSOrderedSame || + [[anAlarm action] caseInsensitiveCompare: @"AUDIO"] == NSOrderedSame) + return anAlarm; + } + + return nil; +} + - (void) updateNextAlarmDateInRow: (NSMutableDictionary *) row forContainer: (id) theContainer { @@ -284,8 +328,8 @@ NSNumber *iCalDistantFutureNumber = nil; if (![(id)self isRecurrent]) { - anAlarm = [[self alarms] objectAtIndex: 0]; - if ([[anAlarm action] caseInsensitiveCompare: @"DISPLAY"] == NSOrderedSame) + anAlarm = [self firstDisplayOrAudioAlarm]; + if (anAlarm) { webstatus = [[anAlarm trigger] value: 0 ofAttribute: @"x-webstatus"]; if (!webstatus @@ -370,8 +414,8 @@ NSNumber *iCalDistantFutureNumber = nil; if ([[o alarms] count]) { - anAlarm = [[o alarms] objectAtIndex: 0]; - if ([[anAlarm action] caseInsensitiveCompare: @"DISPLAY"] == NSOrderedSame) + anAlarm = [self firstDisplayOrAudioAlarm]; + if (anAlarm) { webstatus = [[anAlarm trigger] value: 0 ofAttribute: @"x-webstatus"]; if (!webstatus diff --git a/UI/Scheduler/UIxAppointmentEditor.m b/UI/Scheduler/UIxAppointmentEditor.m index 1ec514ec4..86c26153b 100644 --- a/UI/Scheduler/UIxAppointmentEditor.m +++ b/UI/Scheduler/UIxAppointmentEditor.m @@ -517,21 +517,19 @@ startDate: &eventStartDate endDate: &eventEndDate]; + anAlarm = [event firstDisplayOrAudioAlarm]; + if (resetAlarm) { iCalTrigger *aTrigger; - - anAlarm = [[event alarms] objectAtIndex: 0]; + aTrigger = [anAlarm trigger]; - [aTrigger setValue: 0 ofAttribute: @"x-webstatus" to: @"triggered"]; - + [aTrigger setValue: 0 ofAttribute: @"x-webstatus" to: @"triggered"]; [co saveComponent: master]; } else if (snoozeAlarm) { - anAlarm = [[event alarms] objectAtIndex: 0]; - if ([[anAlarm action] caseInsensitiveCompare: @"DISPLAY"] == NSOrderedSame) - [co snoozeAlarm: snoozeAlarm]; + [co snoozeAlarm: snoozeAlarm]; } } diff --git a/UI/Scheduler/UIxComponentEditor.m b/UI/Scheduler/UIxComponentEditor.m index 1da251cf5..9dc9f2159 100644 --- a/UI/Scheduler/UIxComponentEditor.m +++ b/UI/Scheduler/UIxComponentEditor.m @@ -534,16 +534,16 @@ iRANGE(2); if ([component hasAlarms]) { // We currently have the following limitations for alarms: - // - only the first alarm is considered; - // - the alarm's action must be of type DISPLAY; + // - the alarm's action must be of type DISPLAY or AUDIO (considered as DISPLAY) // - the alarm's trigger value type must be DURATION. - anAlarm = [[component alarms] objectAtIndex: 0]; + anAlarm = [component firstSupportedAlarm]; aTrigger = [anAlarm trigger]; ASSIGN (reminderAction, [[anAlarm action] lowercaseString]); - if (([reminderAction isEqualToString: @"display"] - || [reminderAction isEqualToString: @"email"]) - && [[aTrigger valueType] caseInsensitiveCompare: @"DURATION"] == NSOrderedSame) + + // The default value type is DURATION. See http://tools.ietf.org/html/rfc5545#section-3.8.6.3 + if (![[aTrigger valueType] length] || + [[aTrigger valueType] caseInsensitiveCompare: @"DURATION"] == NSOrderedSame) { duration = [aTrigger flattenedValuesForKey: @""]; i = [reminderValues indexOfObject: duration]; diff --git a/UI/Scheduler/UIxTaskEditor.m b/UI/Scheduler/UIxTaskEditor.m index d1d447549..7eb2984d9 100644 --- a/UI/Scheduler/UIxTaskEditor.m +++ b/UI/Scheduler/UIxTaskEditor.m @@ -459,11 +459,13 @@ timezone: timeZone startDate: &startDate endDate: &dueDate]; + + anAlarm = [todo firstDisplayOrAudioAlarm]; + if (resetAlarm) { iCalTrigger *aTrigger; - anAlarm = [[todo alarms] objectAtIndex: 0]; aTrigger = [anAlarm trigger]; [aTrigger setValue: 0 ofAttribute: @"x-webstatus" to: @"triggered"]; @@ -471,9 +473,7 @@ } else if (snoozeAlarm) { - anAlarm = [[todo alarms] objectAtIndex: 0]; - if ([[anAlarm action] caseInsensitiveCompare: @"DISPLAY"] == NSOrderedSame) - [co snoozeAlarm: snoozeAlarm]; + [co snoozeAlarm: snoozeAlarm]; } } resetAlarm = [[[context request] formValueForKey: @"resetAlarm"] boolValue];