Initial support for multiple alarms and better iCal compatibility

pull/56/head
Ludovic Marcotte 2014-09-12 14:09:28 -04:00
parent 12a4fd05a2
commit b8b3519a40
7 changed files with 69 additions and 23 deletions

View File

@ -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]];
}

View File

@ -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"];
}

View File

@ -23,6 +23,7 @@
#import <NGCards/iCalEntityObject.h>
@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;

View File

@ -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

View File

@ -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];
}
}

View File

@ -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];

View File

@ -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];