Initial JSON actions to get/set an event
parent
f694f57638
commit
f9271b747c
|
@ -35,7 +35,7 @@ extern NSNumber *iCalDistantFutureNumber;
|
|||
|
||||
+ (void) initializeSOGoExtensions;
|
||||
|
||||
- (NSDictionary *) attributes;
|
||||
- (NSDictionary *) attributesInContext: (WOContext *) context;
|
||||
- (void) setAttributes: (NSDictionary *) data
|
||||
inContext: (WOContext *) context;
|
||||
|
||||
|
@ -44,7 +44,6 @@ extern NSNumber *iCalDistantFutureNumber;
|
|||
|
||||
- (iCalPerson *) userAsAttendee: (SOGoUser *) user;
|
||||
|
||||
- (NSArray *) attendeeUIDs;
|
||||
- (BOOL) isStillRelevant;
|
||||
|
||||
- (id) itipEntryWithMethod: (NSString *) method;
|
||||
|
@ -52,7 +51,7 @@ extern NSNumber *iCalDistantFutureNumber;
|
|||
- (NSArray *) attendeesWithoutUser: (SOGoUser *) user;
|
||||
|
||||
- (int) priorityNumber;
|
||||
- (NSString *) createdBy;
|
||||
- (NSDictionary *) createdBy;
|
||||
|
||||
- (NSNumber *) quickRecordDateAsNumber: (NSCalendarDate *) _date
|
||||
withOffset: (int) offset
|
||||
|
|
|
@ -44,11 +44,13 @@
|
|||
#import <NGObjWeb/WOContext+SoObjects.h>
|
||||
|
||||
#import <SOGo/NSArray+Utilities.h>
|
||||
#import <SOGo/SOGoSource.h>
|
||||
#import <SOGo/SOGoUser.h>
|
||||
#import <SOGo/SOGoUserDefaults.h>
|
||||
#import <SOGo/SOGoUserManager.h>
|
||||
|
||||
#import "iCalPerson+SOGo.h"
|
||||
|
||||
#import "iCalAlarm+SOGo.h"
|
||||
#import "iCalCalendar+SOGo.h"
|
||||
#import "iCalEntityObject+SOGo.h"
|
||||
|
||||
|
@ -70,18 +72,23 @@ NSNumber *iCalDistantFutureNumber = nil;
|
|||
/**
|
||||
* @see [UIxAppointmentEditor viewAction]
|
||||
*/
|
||||
- (NSDictionary *) attributes
|
||||
- (NSDictionary *) attributesInContext: (WOContext *) context
|
||||
{
|
||||
NSArray *elements;
|
||||
NSMutableArray *attendees;
|
||||
NSDictionary *organizerData;
|
||||
NSMutableDictionary *data, *attendeeData, *alarmData;
|
||||
NSDictionary *contactData;
|
||||
NSMutableDictionary *data, *organizerData, *attendeeData, *alarmData;
|
||||
NSEnumerator *attendeesList;
|
||||
NSString *uid, *domain, *sentBy;
|
||||
NSObject <SOGoSource> *source;
|
||||
SOGoUserManager *um;
|
||||
iCalPerson *organizer, *currentAttendee;
|
||||
iCalAlarm *alarm;
|
||||
iCalTrigger *trigger;
|
||||
id value;
|
||||
|
||||
um = [SOGoUserManager sharedUserManager];
|
||||
|
||||
data = [NSMutableDictionary dictionaryWithObjectsAndKeys:
|
||||
[[self tag] lowercaseString], @"component",
|
||||
[self summary], @"summary",
|
||||
|
@ -90,33 +97,46 @@ NSNumber *iCalDistantFutureNumber = nil;
|
|||
|
||||
value = [self location];
|
||||
if (value) [data setObject: value forKey: @"location"];
|
||||
if ([self comment]) [data setObject: [self comment] forKey: @"comment"];
|
||||
if ([self attach]) [data setObject: [[self attach] absoluteString] forKey: @"attachUrl"];
|
||||
if ([self accessClass]) [data setObject: [[self accessClass] lowercaseString] forKey: @"classification"];
|
||||
if ([self status]) [data setObject: [self status] forKey: @"status"];
|
||||
if ([self createdBy]) [data setObject: [self createdBy] forKey: @"createdBy"];
|
||||
|
||||
value = [self comment];
|
||||
if (value) [data setObject: value forKey: @"comment"];
|
||||
|
||||
value = [self attach];
|
||||
if (value) [data setObject: [value absoluteString] forKey: @"attachUrl"];
|
||||
|
||||
value = [self accessClass];
|
||||
if (value) [data setObject: [value lowercaseString] forKey: @"classification"];
|
||||
|
||||
value = [self status];
|
||||
if (value) [data setObject: value forKey: @"status"];
|
||||
|
||||
value = [self createdBy];
|
||||
if (value) [data setObject: value forKey: @"createdBy"];
|
||||
|
||||
// Categories
|
||||
elements = [self categories];
|
||||
if ([elements count])
|
||||
[data setObject: elements forKey: @"categories"];
|
||||
|
||||
// Send appointment notifications
|
||||
// Send appointment notifications when the custom tag is *not* set
|
||||
value = [self firstChildWithTag: @"X-SOGo-Send-Appointment-Notifications"];
|
||||
[data setObject: [NSNumber numberWithBool: (value? 1:0)] forKey: @"sendAppointmentNotifications"];
|
||||
[data setObject: [NSNumber numberWithBool: (value? 0:1)] forKey: @"sendAppointmentNotifications"];
|
||||
|
||||
// Organizer
|
||||
organizer = [self organizer];
|
||||
if (organizer)
|
||||
{
|
||||
organizerData = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
[organizer rfc822Email], @"email",
|
||||
[organizer cnWithoutQuotes], @"name",
|
||||
nil];
|
||||
organizerData = [NSMutableDictionary dictionaryWithObjectsAndKeys:
|
||||
[organizer rfc822Email], @"email",
|
||||
[organizer cnWithoutQuotes], @"name",
|
||||
nil];
|
||||
uid = [organizer uid];
|
||||
if ([uid length]) [organizerData setObject: uid forKey: @"uid"];
|
||||
sentBy = [organizer sentBy];
|
||||
if ([sentBy length]) [organizerData setObject: sentBy forKey: @"sentBy"];
|
||||
[data setObject: organizerData forKey: @"organizer"];
|
||||
}
|
||||
|
||||
|
||||
// Attendees
|
||||
attendees = [NSMutableArray array];
|
||||
attendeesList = [[self attendees] objectEnumerator];
|
||||
|
@ -126,29 +146,28 @@ NSNumber *iCalDistantFutureNumber = nil;
|
|||
[currentAttendee rfc822Email], @"email",
|
||||
[currentAttendee cnWithoutQuotes], @"name",
|
||||
nil];
|
||||
if ([currentAttendee uid]) [attendeeData setObject: [currentAttendee uid] forKey: @"uid"];
|
||||
// TODO: restore support for MS Exchange
|
||||
// uid = [um getUIDForEmail: [currentAttendee rfc822Email]];
|
||||
// if (uid != nil)
|
||||
// [currentAttendeeData setObject: uid
|
||||
// forKey: @"uid"];
|
||||
// else
|
||||
// {
|
||||
// domain = [[context activeUser] domain];
|
||||
// contacts = [um fetchContactsMatching: [currentAttendee rfc822Email] inDomain: domain];
|
||||
// if ([contacts count] == 1)
|
||||
// {
|
||||
// contact = [contacts lastObject];
|
||||
// source = [contact objectForKey: @"source"];
|
||||
// if ([source conformsToProtocol: @protocol (SOGoDNSource)] &&
|
||||
// [[(NSObject <SOGoDNSource>*) source MSExchangeHostname] length])
|
||||
// {
|
||||
// uid = [NSString stringWithFormat: @"%@:%@", [[context activeUser] login],
|
||||
// [contact valueForKey: @"c_uid"]];
|
||||
// [currentAttendeeData setObject: uid forKey: @"uid"];
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
if ((uid = [currentAttendee uid]))
|
||||
{
|
||||
[attendeeData setObject: uid forKey: @"uid"];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Search for attendee in global contacts sources that are associated with a MS Exchange server
|
||||
domain = [[context activeUser] domain];
|
||||
elements = [um fetchContactsMatching: [currentAttendee rfc822Email] inDomain: domain];
|
||||
if ([elements count] == 1)
|
||||
{
|
||||
contactData = [elements lastObject];
|
||||
source = [contactData objectForKey: @"source"];
|
||||
if ([source conformsToProtocol: @protocol (SOGoDNSource)] &&
|
||||
[[(NSObject <SOGoDNSource>*) source MSExchangeHostname] length])
|
||||
{
|
||||
uid = [NSString stringWithFormat: @"%@:%@", [[context activeUser] login],
|
||||
[contactData valueForKey: @"c_uid"]];
|
||||
[attendeeData setObject: uid forKey: @"uid"];
|
||||
}
|
||||
}
|
||||
}
|
||||
[attendeeData setObject: [[currentAttendee partStat] lowercaseString] forKey: @"status"];
|
||||
[attendeeData setObject: [[currentAttendee role] lowercaseString] forKey: @"role"];
|
||||
if ([[currentAttendee delegatedTo] length])
|
||||
|
@ -193,6 +212,177 @@ NSNumber *iCalDistantFutureNumber = nil;
|
|||
return data;
|
||||
}
|
||||
|
||||
- (void) _setAttendees: (NSArray *) attendees
|
||||
{
|
||||
NSMutableArray *newAttendees;
|
||||
NSUInteger count, max;
|
||||
NSString *currentEmail;
|
||||
iCalPerson *currentAttendee;
|
||||
NSString *role, *partstat;
|
||||
NSDictionary *currentData;
|
||||
|
||||
if (attendees)
|
||||
{
|
||||
newAttendees = [NSMutableArray array];
|
||||
max = [attendees count];
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
currentData = [attendees objectAtIndex: count];
|
||||
currentEmail = [currentData objectForKey: @"email"];
|
||||
if ([currentEmail length] > 0)
|
||||
{
|
||||
role = [[currentData objectForKey: @"role"] uppercaseString];
|
||||
if (!role)
|
||||
role = @"REQ-PARTICIPANT";
|
||||
if ([role isEqualToString: @"NON-PARTICIPANT"])
|
||||
partstat = @"";
|
||||
else
|
||||
{
|
||||
partstat = [[currentData objectForKey: @"partstat"] uppercaseString];
|
||||
if (!partstat)
|
||||
partstat = @"NEEDS-ACTION";
|
||||
}
|
||||
currentAttendee = [self findAttendeeWithEmail: currentEmail];
|
||||
if (!currentAttendee)
|
||||
{
|
||||
currentAttendee = [iCalPerson elementWithTag: @"attendee"];
|
||||
[currentAttendee setCn: [currentData objectForKey: @"name"]];
|
||||
[currentAttendee setEmail: currentEmail];
|
||||
}
|
||||
[currentAttendee
|
||||
setRsvp: ([role isEqualToString: @"NON-PARTICIPANT"]
|
||||
? @"FALSE"
|
||||
: @"TRUE")];
|
||||
[currentAttendee setRole: role];
|
||||
[currentAttendee setPartStat: partstat];
|
||||
[newAttendees addObject: currentAttendee];
|
||||
}
|
||||
}
|
||||
[self setAttendees: newAttendees];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) _appendAttendeesToEmailAlarm: (iCalAlarm *) alarm
|
||||
{
|
||||
NSArray *attendees;
|
||||
NSMutableArray *aAttendees;
|
||||
int count, max;
|
||||
iCalPerson *currentAttendee, *aAttendee;
|
||||
|
||||
attendees = [self attendees];
|
||||
max = [attendees count];
|
||||
aAttendees = [NSMutableArray arrayWithCapacity: max];
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
currentAttendee = [attendees objectAtIndex: count];
|
||||
aAttendee = [iCalPerson elementWithTag: @"attendee"];
|
||||
[aAttendee setCn: [currentAttendee cn]];
|
||||
[aAttendee setEmail: [currentAttendee rfc822Email]];
|
||||
[aAttendees addObject: aAttendee];
|
||||
}
|
||||
[alarm setAttendees: aAttendees];
|
||||
}
|
||||
|
||||
- (void) _setAlarm: (NSDictionary *) alarm
|
||||
forOwner: (NSString *) owner
|
||||
{
|
||||
iCalAlarm *anAlarm;
|
||||
NSString *reminderAction, *reminderUnit, *reminderQuantity, *reminderReference, *reminderRelation;
|
||||
BOOL reminderEmailAttendees, reminderEmailOrganizer;
|
||||
|
||||
reminderAction = [alarm objectForKey: @"action"];
|
||||
reminderUnit = [alarm objectForKey: @"unit"];
|
||||
reminderQuantity = [alarm objectForKey: @"quantity"];
|
||||
reminderReference = [alarm objectForKey: @"reference"];
|
||||
reminderRelation = [alarm objectForKey: @"relation"];
|
||||
reminderEmailAttendees = [[alarm objectForKey: @"attendees"] boolValue];
|
||||
reminderEmailOrganizer = [[alarm objectForKey: @"organizer"] boolValue];
|
||||
anAlarm = [iCalAlarm alarmForEvent: self
|
||||
owner: owner
|
||||
action: reminderAction
|
||||
unit: reminderUnit
|
||||
quantity: reminderQuantity
|
||||
reference: reminderReference
|
||||
reminderRelation: reminderRelation
|
||||
emailAttendees: reminderEmailAttendees
|
||||
emailOrganizer: reminderEmailOrganizer];
|
||||
|
||||
// If there was an unsupported alarm defined in the event, it will be deleted.
|
||||
[self removeAllAlarms];
|
||||
if (anAlarm)
|
||||
{
|
||||
[self addToAlarms: anAlarm];
|
||||
[anAlarm release];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see [UIxAppointmentEditor saveAction]
|
||||
*/
|
||||
- (void) setAttributes: (NSDictionary *) data
|
||||
inContext: (WOContext *) context
|
||||
{
|
||||
NSString *owner;
|
||||
id o, sendAppointmentNotifications;
|
||||
|
||||
o = [data objectForKey: @"summary"];
|
||||
if ([o isKindOfClass: [NSString class]])
|
||||
[self setSummary: o];
|
||||
|
||||
o = [data objectForKey: @"priority"];
|
||||
if ([o isKindOfClass: [NSNumber class]])
|
||||
[self setPriority: [NSString stringWithFormat: @"%d", [o intValue]]];
|
||||
|
||||
o = [data objectForKey: @"location"];
|
||||
if ([o isKindOfClass: [NSString class]])
|
||||
[self setLocation: o];
|
||||
|
||||
o = [data objectForKey: @"comment"];
|
||||
if ([o isKindOfClass: [NSString class]])
|
||||
[self setComment: [o stringByReplacingString: @"\r\n" withString: @"\n"]];
|
||||
|
||||
o = [data objectForKey: @"attachUrl"];
|
||||
if ([o isKindOfClass: [NSString class]])
|
||||
[self setAttach: o];
|
||||
|
||||
o = [data objectForKey: @"classification"];
|
||||
if ([o isKindOfClass: [NSString class]])
|
||||
[self setAccessClass: [o uppercaseString]];
|
||||
|
||||
o = [data objectForKey: @"status"];
|
||||
if ([o isKindOfClass: [NSString class]])
|
||||
[self setStatus: o];
|
||||
|
||||
o = [data objectForKey: @"categories"];
|
||||
if ([o isKindOfClass: [NSArray class]])
|
||||
[self setCategories: o];
|
||||
|
||||
o = [data objectForKey: @"sendAppointmentNotifications"];
|
||||
if ([o isKindOfClass: [NSNumber class]])
|
||||
{
|
||||
sendAppointmentNotifications = [self firstChildWithTag: @"X-SOGo-Send-Appointment-Notifications"];
|
||||
if (!sendAppointmentNotifications && ![o boolValue])
|
||||
[self addChild: [CardElement simpleElementWithTag: @"X-SOGo-Send-Appointment-Notifications" value: @"NO"]];
|
||||
else if (sendAppointmentNotifications && [o boolValue])
|
||||
[self removeChild: sendAppointmentNotifications];
|
||||
}
|
||||
|
||||
o = [data objectForKey: @"attendees"];
|
||||
if ([o isKindOfClass: [NSArray class]])
|
||||
[self _setAttendees: o];
|
||||
|
||||
o = [data objectForKey: @"alarm"];
|
||||
if ([o isKindOfClass: [NSDictionary class]])
|
||||
{
|
||||
owner = [data objectForKey: @"owner"];
|
||||
[self _setAlarm: o forOwner: owner];
|
||||
}
|
||||
|
||||
// Other attributes depend on the client object and therefore are set in [UIxComponentEditor setAttributes:]:
|
||||
// - organizer & "created-by"
|
||||
// - timestamps (creation/modification)
|
||||
}
|
||||
|
||||
- (BOOL) userIsAttendee: (SOGoUser *) user
|
||||
{
|
||||
NSEnumerator *attendees;
|
||||
|
@ -243,10 +433,11 @@ NSNumber *iCalDistantFutureNumber = nil;
|
|||
|
||||
if ([mail length])
|
||||
return [user hasEmail: mail];
|
||||
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
/*
|
||||
- (NSArray *) attendeeUIDs
|
||||
{
|
||||
NSEnumerator *attendees;
|
||||
|
@ -266,6 +457,7 @@ NSNumber *iCalDistantFutureNumber = nil;
|
|||
|
||||
return uids;
|
||||
}
|
||||
*/
|
||||
|
||||
#warning this method should be implemented in a category of iCalToDo
|
||||
- (BOOL) isStillRelevant
|
||||
|
@ -282,11 +474,11 @@ NSNumber *iCalDistantFutureNumber = nil;
|
|||
|
||||
NSArray *events;
|
||||
int i, count;
|
||||
|
||||
|
||||
newCalendar = [parent mutableCopy];
|
||||
[newCalendar autorelease];
|
||||
[newCalendar setMethod: method];
|
||||
|
||||
|
||||
events = [newCalendar childrenWithTag: tag];
|
||||
count = [events count];
|
||||
if (count > 1)
|
||||
|
@ -379,19 +571,39 @@ NSNumber *iCalDistantFutureNumber = nil;
|
|||
return priorityNumber;
|
||||
}
|
||||
|
||||
- (NSString *) createdBy
|
||||
- (NSDictionary *) createdBy
|
||||
{
|
||||
NSString *created_by;
|
||||
NSString *created_by, *created_by_name, *login;
|
||||
NSDictionary *createdByData;
|
||||
SOGoUser *user;
|
||||
|
||||
created_by_name = nil;
|
||||
createdByData = nil;
|
||||
created_by = [[self firstChildWithTag: @"X-SOGo-Component-Created-By"] flattenedValuesForKey: @""];
|
||||
|
||||
// We consider "SENT-BY" in case our custom header isn't found
|
||||
|
||||
if (![created_by length])
|
||||
{
|
||||
// We consider "SENT-BY" in case our custom header isn't found
|
||||
created_by = [[self organizer] sentBy];
|
||||
}
|
||||
|
||||
return created_by;
|
||||
if ([created_by length])
|
||||
{
|
||||
login = [[SOGoUserManager sharedUserManager] getUIDForEmail: created_by];
|
||||
if (login)
|
||||
{
|
||||
user = [SOGoUser userWithLogin: login];
|
||||
if (user)
|
||||
created_by_name = [user cn];
|
||||
}
|
||||
|
||||
createdByData = [NSDictionary dictionaryWithObjectsAndKeys: created_by, @"email",
|
||||
created_by_name, @"name",
|
||||
nil];
|
||||
}
|
||||
|
||||
return createdByData;
|
||||
;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -478,20 +690,20 @@ NSNumber *iCalDistantFutureNumber = nil;
|
|||
NSCalendarDate *start, *end;
|
||||
NGCalendarDateRange *range;
|
||||
NSMutableArray *alarms;
|
||||
|
||||
|
||||
alarms = [NSMutableArray array];
|
||||
start = [NSCalendarDate date];
|
||||
end = [start addYear:1 month:0 day:0 hour:0 minute:0 second:0];
|
||||
range = [NGCalendarDateRange calendarDateRangeWithStartDate: start
|
||||
endDate: end];
|
||||
|
||||
|
||||
// Always check if container is defined. If not, that means this method
|
||||
// call was reentrant.
|
||||
if (theContainer)
|
||||
{
|
||||
NSTimeInterval now;
|
||||
int i, v, delta, c_startdate, c_nextalarm;
|
||||
|
||||
|
||||
//
|
||||
// Here is the logic:
|
||||
//
|
||||
|
@ -506,12 +718,12 @@ NSNumber *iCalDistantFutureNumber = nil;
|
|||
// If we don't have a match, we pick the event for which its trigger is the closest to the c_nextalarm.
|
||||
//
|
||||
nextAlarmDate = nil;
|
||||
|
||||
|
||||
[theContainer flattenCycleRecord: (id)row
|
||||
forRange: range
|
||||
intoArray: alarms
|
||||
withCalendar: [self parent]];
|
||||
|
||||
|
||||
// We pickup the closest one from now. We remove the actual reminder (ie., 15 mins before - plus 1 minute for roundups)
|
||||
// so we don't pickup the same alarm over and over. This could happen if our alarm popups and the user clicks on "Cancel".
|
||||
// In case of a repetitive event, we want to pickup the next one (next day for example), and not the one that has just
|
||||
|
@ -523,11 +735,11 @@ NSNumber *iCalDistantFutureNumber = nil;
|
|||
c_startdate = [[[alarms objectAtIndex: i] objectForKey: @"c_startdate"] intValue];
|
||||
c_nextalarm = [[[alarms objectAtIndex: i] objectForKey: @"c_nextalarm"] intValue];
|
||||
delta = (c_startdate - now - (c_startdate - c_nextalarm)) - 60;
|
||||
|
||||
|
||||
// If value is not initialized, we grab it right away
|
||||
if (!v && delta > 0)
|
||||
v = delta;
|
||||
|
||||
|
||||
// If we found a smaller delta than before, use it.
|
||||
if (v > 0 && delta > 0 && delta <= v)
|
||||
{
|
||||
|
@ -538,10 +750,10 @@ NSNumber *iCalDistantFutureNumber = nil;
|
|||
o = [[self parent] eventWithRecurrenceID: [[alarms objectAtIndex: i] objectForKey: @"c_recurrence_id"]];
|
||||
else
|
||||
o = [[self parent] todoWithRecurrenceID: [[alarms objectAtIndex: i] objectForKey: @"c_recurrence_id"]];
|
||||
|
||||
|
||||
if (!o)
|
||||
o = self;
|
||||
|
||||
|
||||
if ([[o alarms] count])
|
||||
{
|
||||
anAlarm = [self firstDisplayOrAudioAlarm];
|
||||
|
@ -551,7 +763,7 @@ NSNumber *iCalDistantFutureNumber = nil;
|
|||
if (!webstatus
|
||||
|| ([webstatus caseInsensitiveCompare: @"TRIGGERED"]
|
||||
!= NSOrderedSame))
|
||||
|
||||
|
||||
v = delta;
|
||||
nextAlarmDate = [NSDate dateWithTimeIntervalSince1970: [[[alarms objectAtIndex: i] objectForKey: @"c_nextalarm"] intValue]];
|
||||
}
|
||||
|
@ -565,7 +777,7 @@ NSNumber *iCalDistantFutureNumber = nil;
|
|||
} // if (theContainer)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ([nextAlarmDate isNotNull])
|
||||
[row setObject: [NSNumber numberWithInt: [nextAlarmDate timeIntervalSince1970]]
|
||||
forKey: @"c_nextalarm"];
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* iCalEvent+SOGo.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2007-2014 Inverse inc.
|
||||
* Copyright (C) 2007-2015 Inverse inc.
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -28,7 +28,7 @@
|
|||
@interface iCalEvent (SOGoExtensions)
|
||||
|
||||
- (BOOL) isStillRelevant;
|
||||
- (unsigned int) occurenceInterval;
|
||||
- (NSTimeInterval) occurenceInterval;
|
||||
- (void) updateRecurrenceRulesUntilDate: (NSCalendarDate *) previousEndDate;
|
||||
|
||||
@end
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* iCalEvent+SOGo.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2007-2014 Inverse inc.
|
||||
* Copyright (C) 2007-2015 Inverse inc.
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -22,12 +22,14 @@
|
|||
#import <Foundation/NSCalendarDate.h>
|
||||
#import <Foundation/NSDictionary.h>
|
||||
#import <Foundation/NSEnumerator.h>
|
||||
#import <Foundation/NSTimeZone.h>
|
||||
#import <Foundation/NSValue.h>
|
||||
|
||||
#import <NGExtensions/NGCalendarDateRange.h>
|
||||
#import <NGExtensions/NSNull+misc.h>
|
||||
#import <NGExtensions/NSObject+Logs.h>
|
||||
|
||||
#import <NGCards/iCalCalendar.h>
|
||||
#import <NGCards/iCalDateTime.h>
|
||||
#import <NGCards/iCalTimeZone.h>
|
||||
#import <NGCards/iCalEvent.h>
|
||||
|
@ -36,6 +38,10 @@
|
|||
#import <NGCards/iCalTrigger.h>
|
||||
#import <NGCards/NSString+NGCards.h>
|
||||
|
||||
#import <SoObjects/SOGo/SOGoUser.h>
|
||||
#import <SoObjects/SOGo/SOGoUserDefaults.h>
|
||||
#import <SoObjects/SOGo/WOContext+SOGo.h>
|
||||
|
||||
#import "SOGoAppointmentFolder.h"
|
||||
#import "iCalRepeatableEntityObject+SOGo.h"
|
||||
|
||||
|
@ -47,7 +53,7 @@
|
|||
{
|
||||
NSCalendarDate *now, *lastRecurrence;
|
||||
BOOL isStillRelevent;
|
||||
|
||||
|
||||
now = [NSCalendarDate calendarDate];
|
||||
|
||||
if ([self isRecurrent])
|
||||
|
@ -57,7 +63,7 @@
|
|||
}
|
||||
else
|
||||
isStillRelevent = ([[self endDate] earlierDate: now] == now);
|
||||
|
||||
|
||||
return isStillRelevent;
|
||||
}
|
||||
|
||||
|
@ -114,8 +120,8 @@
|
|||
row = [NSMutableDictionary dictionaryWithCapacity:8];
|
||||
|
||||
[row setObject: @"vevent" forKey: @"c_component"];
|
||||
|
||||
if ([uid isNotNull])
|
||||
|
||||
if ([uid isNotNull])
|
||||
[row setObject:uid forKey: @"c_uid"];
|
||||
else
|
||||
[self logWithFormat: @"WARNING: could not extract a uid from event!"];
|
||||
|
@ -168,11 +174,11 @@
|
|||
forAllDay: isAllDay]
|
||||
forKey: @"c_enddate"];
|
||||
}
|
||||
|
||||
|
||||
if ([self isRecurrent])
|
||||
{
|
||||
NSCalendarDate *date;
|
||||
|
||||
|
||||
date = [self lastPossibleRecurrenceStartDate];
|
||||
if (!date)
|
||||
{
|
||||
|
@ -194,7 +200,7 @@
|
|||
if ([status isNotNull])
|
||||
{
|
||||
int code = 1;
|
||||
|
||||
|
||||
if ([status isEqualToString: @"TENTATIVE"])
|
||||
code = 2;
|
||||
else if ([status isEqualToString: @"CANCELLED"])
|
||||
|
@ -214,12 +220,12 @@
|
|||
if (organizer)
|
||||
{
|
||||
NSString *email;
|
||||
|
||||
|
||||
email = [organizer valueForKey: @"rfc822Email"];
|
||||
if (email)
|
||||
[row setObject:email forKey: @"c_orgmail"];
|
||||
}
|
||||
|
||||
|
||||
/* construct partstates */
|
||||
count = [attendees count];
|
||||
partstates = [[NSMutableString alloc] initWithCapacity:count * 2];
|
||||
|
@ -227,7 +233,7 @@
|
|||
{
|
||||
iCalPerson *p;
|
||||
iCalPersonPartStat stat;
|
||||
|
||||
|
||||
p = [attendees objectAtIndex:i];
|
||||
stat = [p participationStatus];
|
||||
if (i)
|
||||
|
@ -263,7 +269,7 @@
|
|||
}
|
||||
|
||||
/**
|
||||
* Shift the "until dates" of the recurrence rules of the event
|
||||
* Shift the "until dates" of the recurrence rules of the event
|
||||
* with respect to the previous end date of the event.
|
||||
* @param previousEndDate the previous end date of the event
|
||||
*/
|
||||
|
@ -312,12 +318,65 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// From [UIxDatePicker takeValuesFromRequest:inContext:]
|
||||
- (NSCalendarDate *) _dateFromString: (NSString *) dateString
|
||||
inContext: (WOContext *) context
|
||||
{
|
||||
NSInteger dateTZOffset, userTZOffset;
|
||||
NSTimeZone *systemTZ, *userTZ;
|
||||
SOGoUserDefaults *ud;
|
||||
NSCalendarDate *date;
|
||||
|
||||
date = [NSCalendarDate dateWithString: dateString
|
||||
calendarFormat: @"%Y-%m-%d"];
|
||||
if (!date)
|
||||
[self warnWithFormat: @"Could not parse dateString: '%@'", dateString];
|
||||
|
||||
// We must adjust the date timezone because "dateWithString:..." uses the
|
||||
// system timezone, which can be different from the user's. */
|
||||
ud = [[context activeUser] userDefaults];
|
||||
systemTZ = [date timeZone];
|
||||
dateTZOffset = [systemTZ secondsFromGMTForDate: date];
|
||||
userTZ = [ud timeZone];
|
||||
userTZOffset = [userTZ secondsFromGMTForDate: date];
|
||||
if (dateTZOffset != userTZOffset)
|
||||
date = [date dateByAddingYears: 0 months: 0 days: 0
|
||||
hours: 0 minutes: 0
|
||||
seconds: (dateTZOffset - userTZOffset)];
|
||||
[date setTimeZone: userTZ];
|
||||
|
||||
return date;
|
||||
}
|
||||
|
||||
// From [UIxTimeDatePicker takeValuesFromRequest:inContext:]
|
||||
- (void) _adjustDate: (NSCalendarDate **) date
|
||||
withTimeString: (NSString *) timeString
|
||||
inContext: (WOContext *) context
|
||||
{
|
||||
unsigned _year, _month, _day, _hour, _minute;
|
||||
SOGoUserDefaults *ud;
|
||||
NSArray *_time;
|
||||
|
||||
_year = [*date yearOfCommonEra];
|
||||
_month = [*date monthOfYear];
|
||||
_day = [*date dayOfMonth];
|
||||
_time = [timeString componentsSeparatedByString: @":"];
|
||||
_hour = [[_time objectAtIndex: 0] intValue];
|
||||
_minute = [[_time objectAtIndex: 1] intValue];
|
||||
|
||||
ud = [[context activeUser] userDefaults];
|
||||
*date = [NSCalendarDate dateWithYear: _year month: _month day: _day
|
||||
hour: _hour minute: _minute second: 0
|
||||
timeZone: [ud timeZone]];
|
||||
}
|
||||
|
||||
/**
|
||||
* @see [iCalRepeatableEntityObject+SOGo attributes]
|
||||
* @see [iCalEntityObject+SOGo attributes]
|
||||
* @see [UIxAppointmentEditor viewAction]
|
||||
*/
|
||||
- (NSDictionary *) attributes
|
||||
- (NSDictionary *) attributesInContext: (WOContext *) context
|
||||
{
|
||||
NSMutableDictionary *data;
|
||||
|
||||
|
@ -329,4 +388,100 @@
|
|||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see [iCalRepeatableEntityObject+SOGo setAttributes:inContext:]
|
||||
* @see [iCalEntityObject+SOGo setAttributes:inContext:]
|
||||
* @see [UIxAppointmentEditor saveAction]
|
||||
*/
|
||||
- (void) setAttributes: (NSDictionary *) data
|
||||
inContext: (WOContext *) context
|
||||
{
|
||||
NSCalendarDate *aptStartDate, *aptEndDate, *allDayStartDate;
|
||||
NSTimeZone *timeZone;
|
||||
NSInteger offset, nbrDays;
|
||||
iCalDateTime *startDate;
|
||||
iCalTimeZone *tz;
|
||||
SOGoUserDefaults *ud;
|
||||
BOOL isAllDay;
|
||||
id o;
|
||||
|
||||
[super setAttributes: data inContext: context];
|
||||
|
||||
aptStartDate = aptEndDate = nil;
|
||||
|
||||
// Handle start/end dates
|
||||
o = [data objectForKey: @"startDate"];
|
||||
if ([o isKindOfClass: [NSString class]] && [o length])
|
||||
aptStartDate = [self _dateFromString: o inContext: context];
|
||||
|
||||
o = [data objectForKey: @"startTime"];
|
||||
if ([o isKindOfClass: [NSString class]] && [o length])
|
||||
[self _adjustDate: &aptStartDate withTimeString: o inContext: context];
|
||||
|
||||
o = [data objectForKey: @"endDate"];
|
||||
if ([o isKindOfClass: [NSString class]] && [o length])
|
||||
aptEndDate = [self _dateFromString: o inContext: context];
|
||||
|
||||
o = [data objectForKey: @"endTime"];
|
||||
if ([o isKindOfClass: [NSString class]] && [o length])
|
||||
[self _adjustDate: &aptEndDate withTimeString: o inContext: context];
|
||||
|
||||
o = [data objectForKey: @"isTransparent"];
|
||||
if ([o isKindOfClass: [NSNumber class]])
|
||||
[self setTransparency: ([o boolValue]? @"TRANSPARENT" : @"OPAQUE")];
|
||||
|
||||
isAllDay = [[data objectForKey: @"isAllDay"] boolValue];
|
||||
|
||||
if (aptStartDate && aptEndDate)
|
||||
{
|
||||
if (isAllDay)
|
||||
{
|
||||
nbrDays = ((float) abs ([aptEndDate timeIntervalSinceDate: aptStartDate]) / 86400) + 1;
|
||||
// Convert all-day start date to GMT (floating date)
|
||||
ud = [[context activeUser] userDefaults];
|
||||
timeZone = [ud timeZone];
|
||||
offset = [timeZone secondsFromGMTForDate: aptStartDate];
|
||||
allDayStartDate = [aptStartDate dateByAddingYears: 0 months: 0 days: 0
|
||||
hours: 0 minutes: 0
|
||||
seconds: offset];
|
||||
[self setAllDayWithStartDate: allDayStartDate
|
||||
duration: nbrDays];
|
||||
}
|
||||
else
|
||||
{
|
||||
[self setStartDate: aptStartDate];
|
||||
[self setEndDate: aptEndDate];
|
||||
}
|
||||
}
|
||||
|
||||
if (!isAllDay)
|
||||
{
|
||||
// Make sure there's a vTimeZone associated to the event unless it
|
||||
// is an all-day event.
|
||||
startDate = (iCalDateTime *)[self uniqueChildWithTag: @"dtstart"];
|
||||
if (![startDate timeZone])
|
||||
{
|
||||
ud = [[context activeUser] userDefaults];
|
||||
tz = [iCalTimeZone timeZoneForName: [ud timeZoneName]];
|
||||
if ([[self parent] addTimeZone: tz])
|
||||
{
|
||||
[startDate setTimeZone: tz];
|
||||
[(iCalDateTime *)[self uniqueChildWithTag: @"dtend"] setTimeZone: tz];
|
||||
}
|
||||
}
|
||||
}
|
||||
else // if (![[self clientObject] isNew])
|
||||
{
|
||||
// Remove the vTimeZone when dealing with an all-day event.
|
||||
startDate = (iCalDateTime *)[self uniqueChildWithTag: @"dtstart"];
|
||||
tz = [startDate timeZone];
|
||||
if (tz)
|
||||
{
|
||||
[startDate setTimeZone: nil];
|
||||
[(iCalDateTime *)[self uniqueChildWithTag: @"dtend"] setTimeZone: nil];
|
||||
[[self parent] removeChild: tz];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -37,6 +37,10 @@
|
|||
|
||||
#import <NGExtensions/NGCalendarDateRange.h>
|
||||
|
||||
#import <SoObjects/SOGo/SOGoUser.h>
|
||||
#import <SoObjects/SOGo/SOGoUserDefaults.h>
|
||||
#import <SoObjects/SOGo/WOContext+SOGo.h>
|
||||
|
||||
#import "iCalRepeatableEntityObject+SOGo.h"
|
||||
|
||||
@implementation iCalRepeatableEntityObject (SOGoExtensions)
|
||||
|
@ -76,7 +80,7 @@
|
|||
* @see [iCalEvent+SOGo attributes]
|
||||
* @see [UIxAppointmentEditor viewAction]
|
||||
*/
|
||||
- (NSDictionary *) attributes
|
||||
- (NSDictionary *) attributesInContext: (WOContext *) context
|
||||
{
|
||||
NSMutableDictionary *data, *repeat;
|
||||
NSArray *rules;
|
||||
|
@ -110,6 +114,103 @@
|
|||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see [iCalEntityObject+SOGo setAttributes:inContext:]
|
||||
* @see [UIxAppointmentEditor saveAction]
|
||||
*/
|
||||
- (void) setAttributes: (NSDictionary *) data
|
||||
inContext: (WOContext *) context
|
||||
{
|
||||
iCalRecurrenceRule *rule;
|
||||
iCalRecurrenceFrequency frequency;
|
||||
NSCalendarDate *date;
|
||||
SOGoUserDefaults *ud;
|
||||
id repeat, o;
|
||||
|
||||
[super setAttributes: data inContext: context];
|
||||
|
||||
if ([self recurrenceId])
|
||||
// Occurrence of a recurrent object can't have a recurrence rule
|
||||
return;
|
||||
|
||||
repeat = [data objectForKey: @"repeat"];
|
||||
if ([repeat isKindOfClass: [NSDictionary class]])
|
||||
{
|
||||
rule = [iCalRecurrenceRule new];
|
||||
[rule setInterval: @"1"];
|
||||
|
||||
frequency = NSNotFound;
|
||||
o = [repeat objectForKey: @"frequency"];
|
||||
if ([o isKindOfClass: [NSString class]])
|
||||
{
|
||||
frequency = [rule valueForFrequency: o];
|
||||
if ((NSUInteger) frequency == NSNotFound)
|
||||
{
|
||||
if ([o caseInsensitiveCompare: @"BI-WEEKLY"] == NSOrderedSame)
|
||||
{
|
||||
frequency = iCalRecurrenceFrequenceWeekly;
|
||||
[rule setInterval: @"2"];
|
||||
}
|
||||
else if ([o caseInsensitiveCompare: @"EVERY WEEKDAY"] == NSOrderedSame)
|
||||
{
|
||||
frequency = iCalRecurrenceFrequenceDaily;
|
||||
[rule setByDayMask: [iCalByDayMask byDayMaskWithWeekDays]];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
o = [repeat objectForKey: @"interval"];
|
||||
if ([o isKindOfClass: [NSNumber class]])
|
||||
[rule setInterval: [NSString stringWithFormat: @"%i", [o intValue]]];
|
||||
|
||||
o = [repeat objectForKey: @"count"];
|
||||
if ([o isKindOfClass: [NSNumber class]])
|
||||
[rule setRepeatCount: [o intValue]];
|
||||
|
||||
o = [repeat objectForKey: @"until"];
|
||||
if ([o isKindOfClass: [NSString class]])
|
||||
{
|
||||
date = [NSCalendarDate dateWithString: o
|
||||
calendarFormat: @"%Y-%m-%d"];
|
||||
if (date)
|
||||
{
|
||||
// Adjust timezone
|
||||
ud = [[context activeUser] userDefaults];
|
||||
date = [NSCalendarDate dateWithYear: [date yearOfCommonEra]
|
||||
month: [date monthOfYear]
|
||||
day: [date dayOfMonth]
|
||||
hour: 0 minute: 0 second: 0
|
||||
timeZone: [ud timeZone]];
|
||||
[rule setUntilDate: date];
|
||||
}
|
||||
}
|
||||
|
||||
o = [repeat objectForKey: @"days"];
|
||||
if ([o isKindOfClass: [NSArray class]])
|
||||
[rule setByDayMask: [iCalByDayMask byDayMaskWithDaysAndOccurences: o]];
|
||||
|
||||
o = [repeat objectForKey: @"monthdays"];
|
||||
if ([o isKindOfClass: [NSArray class]])
|
||||
[rule setValues: o atIndex: 0 forKey: @"bymonthday"];
|
||||
|
||||
o = [repeat objectForKey: @"months"];
|
||||
if ([o isKindOfClass: [NSArray class]])
|
||||
[rule setValues: o atIndex: 0 forKey: @"bymonth"];
|
||||
}
|
||||
|
||||
if ((NSUInteger) frequency != NSNotFound)
|
||||
[rule setFrequency: frequency];
|
||||
|
||||
[self setRecurrenceRules: [NSArray arrayWithObject: rule]];
|
||||
[rule release];
|
||||
}
|
||||
}
|
||||
else if ([self hasRecurrenceRules])
|
||||
{
|
||||
[self removeAllRecurrenceRules];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *) cycleInfo
|
||||
{
|
||||
NSArray *rules;
|
||||
|
@ -124,7 +225,7 @@
|
|||
rules = [self _indexedRules: [self recurrenceRules]];
|
||||
if (rules)
|
||||
[cycleInfo setObject: rules forKey: @"rules"];
|
||||
|
||||
|
||||
rules = [self _indexedRules: [self exceptionRules]];
|
||||
if (rules)
|
||||
[cycleInfo setObject: rules forKey: @"exRules"];
|
||||
|
@ -163,7 +264,7 @@
|
|||
firstRange = [NGCalendarDateRange calendarDateRangeWithStartDate: start
|
||||
endDate: end];
|
||||
}
|
||||
|
||||
|
||||
return firstRange;
|
||||
}
|
||||
|
||||
|
|
|
@ -301,13 +301,6 @@
|
|||
}
|
||||
else
|
||||
data = @"";
|
||||
else if ([data isKindOfClass: [NSArray class]])
|
||||
{
|
||||
if ([data count] > 0)
|
||||
data = [data objectAtIndex: 0];
|
||||
else
|
||||
data = @"";
|
||||
}
|
||||
[newRecord setObject: data forKey: @"c_telephonenumber"];
|
||||
|
||||
// Custom attribute for group-lookups. See LDAPSource.m where
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* UIxAppointmentEditor.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2007-2014 Inverse inc.
|
||||
* Copyright (C) 2007-2015 Inverse inc.
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -24,43 +24,14 @@
|
|||
#import <SOGoUI/UIxComponent.h>
|
||||
|
||||
@class iCalEvent;
|
||||
@class NSString;
|
||||
|
||||
@interface UIxAppointmentEditor : UIxComponent
|
||||
@interface UIxAppointmentEditor : UIxComponentEditor
|
||||
{
|
||||
iCalEvent *event;
|
||||
BOOL isAllDay, isTransparent, sendAppointmentNotifications;
|
||||
NSCalendarDate *aptStartDate;
|
||||
NSCalendarDate *aptEndDate;
|
||||
NSString *item;
|
||||
SOGoAppointmentFolder *componentCalendar;
|
||||
SOGoDateFormatter *dateFormatter;
|
||||
}
|
||||
|
||||
/* template values */
|
||||
- (NSString *) saveURL;
|
||||
- (iCalEvent *) event;
|
||||
|
||||
/* icalendar values */
|
||||
- (void) setIsAllDay: (BOOL) newIsAllDay;
|
||||
- (BOOL) isAllDay;
|
||||
|
||||
- (void) setIsTransparent: (BOOL) newIsOpaque;
|
||||
- (BOOL) isTransparent;
|
||||
|
||||
- (void) setSendAppointmentNotifications: (BOOL) theBOOL;
|
||||
- (BOOL) sendAppointmentNotifications;
|
||||
|
||||
- (void) setAptStartDate: (NSCalendarDate *) newAptStartDate;
|
||||
- (NSCalendarDate *) aptStartDate;
|
||||
|
||||
- (void) setAptEndDate: (NSCalendarDate *) newAptEndDate;
|
||||
- (NSCalendarDate *) aptEndDate;
|
||||
|
||||
- (NSString *) aptStartDateText;
|
||||
- (NSString *) aptStartDateTimeText;
|
||||
- (NSString *) aptEndDateTimeText;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* UIXAPPOINTMENTEDITOR_H */
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#import <NGObjWeb/NSException+HTTP.h>
|
||||
#import <NGExtensions/NSCalendarDate+misc.h>
|
||||
#import <NGExtensions/NGCalendarDateRange.h>
|
||||
#import <NGExtensions/NSObject+Logs.h>
|
||||
#import <NGExtensions/NSString+misc.h>
|
||||
|
||||
#import <NGCards/iCalAlarm.h>
|
||||
|
@ -73,15 +74,6 @@
|
|||
|
||||
if ((self = [super init]))
|
||||
{
|
||||
aptStartDate = nil;
|
||||
aptEndDate = nil;
|
||||
item = nil;
|
||||
event = nil;
|
||||
isAllDay = NO;
|
||||
isTransparent = NO;
|
||||
sendAppointmentNotifications = YES;
|
||||
componentCalendar = nil;
|
||||
|
||||
user = [[self context] activeUser];
|
||||
ASSIGN (dateFormatter, [user dateFormatterInContext: context]);
|
||||
}
|
||||
|
@ -91,116 +83,16 @@
|
|||
|
||||
- (void) dealloc
|
||||
{
|
||||
[item release];
|
||||
[[event parent] release];
|
||||
[aptStartDate release];
|
||||
[aptEndDate release];
|
||||
[dateFormatter release];
|
||||
[componentCalendar release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
/* template values */
|
||||
- (iCalEvent *) event
|
||||
{
|
||||
if (!event)
|
||||
{
|
||||
event = (iCalEvent *) [[self clientObject] occurence];
|
||||
[[event parent] retain];
|
||||
}
|
||||
|
||||
return event;
|
||||
return (iCalEvent *) component;
|
||||
}
|
||||
|
||||
- (NSString *) rsvpURL
|
||||
{
|
||||
return [NSString stringWithFormat: @"%@/rsvpAppointment",
|
||||
[[self clientObject] baseURL]];
|
||||
}
|
||||
- (NSString *) saveURL
|
||||
{
|
||||
return [NSString stringWithFormat: @"%@/saveAsAppointment",
|
||||
[[self clientObject] baseURL]];
|
||||
}
|
||||
|
||||
/* icalendar values */
|
||||
- (BOOL) isAllDay
|
||||
{
|
||||
NSString *hm;
|
||||
|
||||
hm = [self queryParameterForKey: @"hm"];
|
||||
|
||||
return (isAllDay
|
||||
|| [hm isEqualToString: @"allday"]);
|
||||
}
|
||||
|
||||
- (void) setIsAllDay: (BOOL) newIsAllDay
|
||||
{
|
||||
isAllDay = newIsAllDay;
|
||||
}
|
||||
|
||||
- (BOOL) isTransparent
|
||||
{
|
||||
return isTransparent;
|
||||
}
|
||||
|
||||
- (void) setIsTransparent: (BOOL) newIsTransparent
|
||||
{
|
||||
isTransparent = newIsTransparent;
|
||||
}
|
||||
|
||||
- (void) setSendAppointmentNotifications: (BOOL) theBOOL
|
||||
{
|
||||
sendAppointmentNotifications = theBOOL;
|
||||
}
|
||||
|
||||
- (BOOL) sendAppointmentNotifications
|
||||
{
|
||||
return sendAppointmentNotifications;
|
||||
}
|
||||
|
||||
|
||||
- (void) setAptStartDate: (NSCalendarDate *) newAptStartDate
|
||||
{
|
||||
ASSIGN (aptStartDate, newAptStartDate);
|
||||
}
|
||||
|
||||
- (NSCalendarDate *) aptStartDate
|
||||
{
|
||||
return aptStartDate;
|
||||
}
|
||||
|
||||
- (void) setAptEndDate: (NSCalendarDate *) newAptEndDate
|
||||
{
|
||||
ASSIGN (aptEndDate, newAptEndDate);
|
||||
}
|
||||
|
||||
- (NSCalendarDate *) aptEndDate
|
||||
{
|
||||
return aptEndDate;
|
||||
}
|
||||
|
||||
- (void) setItem: (NSString *) newItem
|
||||
{
|
||||
ASSIGN (item, newItem);
|
||||
}
|
||||
|
||||
- (NSString *) item
|
||||
{
|
||||
return item;
|
||||
}
|
||||
|
||||
- (SOGoAppointmentFolder *) componentCalendar
|
||||
{
|
||||
return componentCalendar;
|
||||
}
|
||||
|
||||
- (void) setComponentCalendar: (SOGoAppointmentFolder *) _componentCalendar
|
||||
{
|
||||
ASSIGN (componentCalendar, _componentCalendar);
|
||||
}
|
||||
|
||||
- (NSString *) formattedDateString: (NSCalendarDate *) date
|
||||
- (NSString *) _dateString: (NSCalendarDate *) date
|
||||
{
|
||||
char buf[22];
|
||||
NSNumber *day, *month, *year;
|
||||
|
@ -217,14 +109,7 @@
|
|||
return [NSString stringWithCString:buf];
|
||||
}
|
||||
|
||||
|
||||
/* read-only event */
|
||||
- (BOOL) startDateIsEqualToEndDate
|
||||
{
|
||||
return [aptStartDate isEqualToDate: aptEndDate];
|
||||
}
|
||||
|
||||
/* actions */
|
||||
/*
|
||||
- (NSCalendarDate *) newStartDate
|
||||
{
|
||||
NSCalendarDate *newStartDate, *now;
|
||||
|
@ -262,7 +147,9 @@
|
|||
|
||||
return newStartDate;
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
- (id <WOActionResults>) defaultAction
|
||||
{
|
||||
NSCalendarDate *startDate, *endDate;
|
||||
|
@ -316,7 +203,7 @@
|
|||
endDate = [endDate dateByAddingYears:0 months:0 days:0 hours:0 minutes:0
|
||||
seconds:-offset];
|
||||
}
|
||||
isTransparent = ![event isOpaque];
|
||||
isTransparent = ![event isOpaque];
|
||||
sendAppointmentNotifications = ([event firstChildWithTag: @"X-SOGo-Send-Appointment-Notifications"] ? NO : YES);
|
||||
}
|
||||
|
||||
|
@ -328,15 +215,18 @@
|
|||
|
||||
return self;
|
||||
}
|
||||
*/
|
||||
|
||||
- (void) _adjustRecurrentRules
|
||||
{
|
||||
iCalEvent *event;
|
||||
iCalRecurrenceRule *rule;
|
||||
NSEnumerator *rules;
|
||||
NSCalendarDate *untilDate;
|
||||
SOGoUserDefaults *ud;
|
||||
NSTimeZone *timeZone;
|
||||
|
||||
|
||||
event = [self event];
|
||||
rules = [[event recurrenceRules] objectEnumerator];
|
||||
ud = [[context activeUser] userDefaults];
|
||||
timeZone = [ud timeZone];
|
||||
|
@ -492,66 +382,151 @@
|
|||
return response;
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
/**
|
||||
* @api {post} /so/:username/Calendar/:calendarId/:appointmentId/save Save event
|
||||
* @apiVersion 1.0.0
|
||||
* @apiName PostEventSave
|
||||
* @apiGroup Calendar
|
||||
* @apiExample {curl} Example usage:
|
||||
* curl -i http://localhost/SOGo/so/sogo1/Calendar/personal/71B6-54904400-1-7C308500.ics/save \
|
||||
* -H 'Content-Type: application/json' \
|
||||
* -d '{ "summary": "Meeting", "startDate": "2015-01-28", "startTime": "10:00", \
|
||||
* "endDate": "2015-01-28", "endTime": "12:00" }'
|
||||
*
|
||||
* Save in [iCalEvent+SOGo setAttributes:inContext:]
|
||||
*
|
||||
* @apiParam {String} startDate Start date (YYYY-MM-DD)
|
||||
* @apiParam {String} startTime Start time (HH:MM)
|
||||
* @apiParam {String} endDate End date (YYYY-MM-DD)
|
||||
* @apiParam {String} endTime End time (HH:MM)
|
||||
* @apiParam {Number} [isAllDay] 1 if event is all-day
|
||||
* @apiParam {Number} isTransparent 1 if the event is not opaque
|
||||
*
|
||||
* Save in [iCalEntityObject+SOGo setAttributes:inContext:]
|
||||
*
|
||||
* @apiParam {Number} [sendAppointmentNotifications] 0 if notifications must not be sent
|
||||
* @apiParam {String} [summary] Summary
|
||||
* @apiParam {String} [location] Location
|
||||
* @apiParam {String} [comment] Comment
|
||||
* @apiParam {String} [status] Status
|
||||
* @apiParam {String} [attachUrl] Attached URL
|
||||
* @apiParam {Number} [priority] Priority
|
||||
* @apiParam {NSString} [classification] Either public, confidential or private
|
||||
* @apiParam {String[]} [categories] Categories
|
||||
* @apiParam {Object[]} [attendees] List of attendees
|
||||
* @apiParam {String} [attendees.name] Attendee's name
|
||||
* @apiParam {String} attendees.email Attendee's email address
|
||||
* @apiParam {String} [attendees.uid] System user ID
|
||||
* @apiParam {String} attendees.status Attendee's participation status
|
||||
* @apiParam {String} [attendees.role] Either CHAIR, REQ-PARTICIPANT, OPT-PARTICIPANT, or NON-PARTICIPANT
|
||||
* @apiParam {String} [attendees.delegatedTo] User that the original request was delegated to
|
||||
* @apiParam {String} [attendees.delegatedFrom] User the request was delegated from
|
||||
* @apiParam {Object[]} [alarm] Alarm definition
|
||||
* @apiParam {String} alarm.action Either display or email
|
||||
* @apiParam {Number} alarm.quantity Quantity of units
|
||||
* @apiParam {String} alarm.unit Either MINUTES, HOURS, or DAYS
|
||||
* @apiParam {String} alarm.reference Either BEFORE or AFTER
|
||||
* @apiParam {String} alarm.relation Either START or END
|
||||
* @apiParam {Boolean} [alarm.attendees] Alert attendees by email if true and action is email
|
||||
* @apiParam {Object} [alarm.organizer] Alert organizer at this email address if action is email
|
||||
* @apiParam {String} [alarm.organizer.name] Attendee's name
|
||||
* @apiParam {String} alarm.organizer.email Attendee's email address
|
||||
*
|
||||
* Save in [iCalRepeatbleEntityObject+SOGo setAttributes:inContext:]
|
||||
*
|
||||
* @apiParam {Object} [repeat] Recurrence rule definition
|
||||
* @apiParam {String} repeat.frequency Either daily, every weekday, weekly, bi-weekly, monthly, or yearly
|
||||
* @apiParam {Number} repeat.interval Intervals the recurrence rule repeats
|
||||
* @apiParam {String} [repeat.count] Number of occurrences at which to range-bound the recurrence
|
||||
* @apiParam {String} [repeat.until] A date (YYYY-MM-DD) that bounds the recurrence rule in an inclusive manner
|
||||
* @apiParam {Object[]} [repeat.days] List of days of the week (by day mask)
|
||||
* @apiParam {String} [repeat.days.day] Day of the week (SU, MO, TU, WE, TH, FR, SA)
|
||||
* @apiParam {Number} [repeat.days.occurence] Occurrence of a specific day within the monthly or yearly rule (values are -5 to 5)
|
||||
* @apiParam {Number[]} [repeat.months] List of months of the year (values are 1 to 12)
|
||||
* @apiParam {Number[]} [repeat.monthdays] Days of the month (values are 1 to 31)
|
||||
*
|
||||
* Save in [UIxComponentEditor setAttributes:]
|
||||
*
|
||||
* @apiParam {Object} [organizer] Appointment organizer
|
||||
* @apiParam {String} organizer.name Organizer's name
|
||||
* @apiParam {String} organizer.email Organizer's email address
|
||||
*
|
||||
* @apiError (Error 500) {Object} error The error message
|
||||
*/
|
||||
- (id <WOActionResults>) saveAction
|
||||
{
|
||||
NSDictionary *params;
|
||||
NSString *jsonResponse;
|
||||
NSException *ex;
|
||||
iCalEvent *event;
|
||||
SOGoAppointmentFolder *previousCalendar;
|
||||
SOGoAppointmentObject *co;
|
||||
NSString *jsonResponse;
|
||||
SoSecurityManager *sm;
|
||||
NSException *ex;
|
||||
WORequest *request;
|
||||
|
||||
event = [self event];
|
||||
co = [self clientObject];
|
||||
if ([co isKindOfClass: [SOGoAppointmentOccurence class]])
|
||||
co = [co container];
|
||||
previousCalendar = [co container];
|
||||
sm = [SoSecurityManager sharedSecurityManager];
|
||||
|
||||
ex = nil;
|
||||
|
||||
if ([event hasRecurrenceRules])
|
||||
[self _adjustRecurrentRules];
|
||||
|
||||
if ([co isNew])
|
||||
request = [context request];
|
||||
params = [[request contentAsString] objectFromJSONString];
|
||||
if (params == nil)
|
||||
{
|
||||
if (componentCalendar
|
||||
&& ![[componentCalendar ocsPath]
|
||||
isEqualToString: [previousCalendar ocsPath]])
|
||||
{
|
||||
// New event in a different calendar -- make sure the user can
|
||||
// write to the selected calendar since the rights were verified
|
||||
// on the calendar specified in the URL, not on the selected
|
||||
// calendar of the popup menu.
|
||||
if (![sm validatePermission: SoPerm_AddDocumentsImagesAndFiles
|
||||
onObject: componentCalendar
|
||||
inContext: context])
|
||||
co = [componentCalendar lookupName: [co nameInContainer]
|
||||
inContext: context
|
||||
acquire: NO];
|
||||
}
|
||||
|
||||
// Save the event.
|
||||
ex = [co saveComponent: event];
|
||||
ex = [NSException exceptionWithName: @"JSONParsingException"
|
||||
reason: @"Can't parse JSON string"
|
||||
userInfo: nil];
|
||||
}
|
||||
else
|
||||
{
|
||||
// The event was modified -- save it.
|
||||
ex = [co saveComponent: event];
|
||||
[self setAttributes: params];
|
||||
|
||||
if (componentCalendar
|
||||
&& ![[componentCalendar ocsPath]
|
||||
isEqualToString: [previousCalendar ocsPath]])
|
||||
if ([event hasRecurrenceRules])
|
||||
[self _adjustRecurrentRules];
|
||||
|
||||
if ([co isNew])
|
||||
{
|
||||
// The event was moved to a different calendar.
|
||||
if (![sm validatePermission: SoPerm_DeleteObjects
|
||||
onObject: previousCalendar
|
||||
inContext: context])
|
||||
if (componentCalendar
|
||||
&& ![[componentCalendar ocsPath]
|
||||
isEqualToString: [previousCalendar ocsPath]])
|
||||
{
|
||||
// New event in a different calendar -- make sure the user can
|
||||
// write to the selected calendar since the rights were verified
|
||||
// on the calendar specified in the URL, not on the selected
|
||||
// calendar of the popup menu.
|
||||
if (![sm validatePermission: SoPerm_AddDocumentsImagesAndFiles
|
||||
onObject: componentCalendar
|
||||
inContext: context])
|
||||
ex = [co moveToFolder: componentCalendar];
|
||||
onObject: componentCalendar
|
||||
inContext: context])
|
||||
co = [componentCalendar lookupName: [co nameInContainer]
|
||||
inContext: context
|
||||
acquire: NO];
|
||||
}
|
||||
|
||||
// Save the event.
|
||||
ex = [co saveComponent: event];
|
||||
}
|
||||
else
|
||||
{
|
||||
// The event was modified -- save it.
|
||||
ex = [co saveComponent: event];
|
||||
|
||||
if (componentCalendar
|
||||
&& ![[componentCalendar ocsPath]
|
||||
isEqualToString: [previousCalendar ocsPath]])
|
||||
{
|
||||
// The event was moved to a different calendar.
|
||||
if (![sm validatePermission: SoPerm_DeleteObjects
|
||||
onObject: previousCalendar
|
||||
inContext: context])
|
||||
{
|
||||
if (![sm validatePermission: SoPerm_AddDocumentsImagesAndFiles
|
||||
onObject: componentCalendar
|
||||
inContext: context])
|
||||
ex = [co moveToFolder: componentCalendar];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -565,9 +540,9 @@
|
|||
else
|
||||
jsonResponse = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||
@"success", @"status", nil];
|
||||
|
||||
|
||||
return [self responseWithStatus: 200
|
||||
andString: [jsonResponse jsonRepresentation]];
|
||||
andJSONRepresentation: jsonResponse];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -590,35 +565,41 @@
|
|||
* @apiSuccess (Success 200) {String} endDate End date (YYYY-MM-DD)
|
||||
* @apiSuccess (Success 200) {String} localizedEndDate Formatted end date
|
||||
* @apiSuccess (Success 200) {String} endTime Formatted end time
|
||||
*
|
||||
* From [iCalEvent+SOGo attributes]
|
||||
*
|
||||
* @apiSuccess (Success 200) {Number} isAllDay 1 if event is all-day
|
||||
* @apiSuccess (Success 200) {Number} isTransparent 1 if the event is not opaque
|
||||
* @apiSuccess (Success 200) {Number} sendAppointmentNotifications 1 if notifications must be sent
|
||||
*
|
||||
* From [iCalEntityObject+SOGo attributes]
|
||||
*
|
||||
* @apiSuccess (Success 200) {Number} sendAppointmentNotifications 1 if notifications must be sent
|
||||
* @apiSuccess (Success 200) {String} component "vevent"
|
||||
* @apiSuccess (Success 200) {String} summary Summary
|
||||
* @apiSuccess (Success 200) {String} location Location
|
||||
* @apiSuccess (Success 200) {String} comment Comment
|
||||
* @apiSuccess (Success 200) {String} [location] Location
|
||||
* @apiSuccess (Success 200) {String} [comment] Comment
|
||||
* @apiSuccess (Success 200) {String} [status] Status
|
||||
* @apiSuccess (Success 200) {String} [attachUrl] Attached URL
|
||||
* @apiSuccess (Success 200) {String} createdBy Value of custom header X-SOGo-Component-Created-By or organizer's "SENT-BY"
|
||||
* @apiSuccess (Success 200) {String} [createdBy] Value of custom header X-SOGo-Component-Created-By or organizer's "SENT-BY"
|
||||
* @apiSuccess (Success 200) {Number} priority Priority
|
||||
* @apiSuccess (Success 200) {NSString} classification Either public, confidential or private
|
||||
* @apiSuccess (Success 200) {NSString} [classification] Either public, confidential or private
|
||||
* @apiSuccess (Success 200) {String[]} [categories] Categories
|
||||
* @apiSuccess (Success 200) {Object} [organizer] Appointment organizer
|
||||
* @apiSuccess (Success 200) {String} organizer.name Organizer's name
|
||||
* @apiSuccess (Success 200) {String} [organizer.name] Organizer's name
|
||||
* @apiSuccess (Success 200) {String} organizer.email Organizer's email address
|
||||
* @apiSuccess (Success 200) {String} [organizer.uid] Organizer's user ID
|
||||
* @apiSuccess (Success 200) {String} [organizer.sentBy] Email address of user that is acting on behalf of the calendar owner
|
||||
* @apiSuccess (Success 200) {Object[]} [attendees] List of attendees
|
||||
* @apiSuccess (Success 200) {String} [attendees.name] Attendee's name
|
||||
* @apiSuccess (Success 200) {String} attendees.email Attendee's email address
|
||||
* @apiSuccess (Success 200) {String} [attendees.uid] System user ID
|
||||
* @apiSuccess (Success 200) {String} attendees.status Attendee's participation status
|
||||
* @apiSuccess (Success 200) {String} [attendees.role] Attendee's role
|
||||
* @apiSuccess (Success 200) {String} [attendees.role] Either CHAIR, REQ-PARTICIPANT, OPT-PARTICIPANT, or NON-PARTICIPANT
|
||||
* @apiSuccess (Success 200) {String} [attendees.delegatedTo] User that the original request was delegated to
|
||||
* @apiSuccess (Success 200) {String} [attendees.delegatedFrom] User the request was delegated from
|
||||
* @apiSuccess (Success 200) {Object[]} [alarm] Alarm definition
|
||||
* @apiSuccess (Success 200) {String} alarm.action Either display or email
|
||||
* @apiSuccess (Success 200) {String} alarm.quantity Quantity of units
|
||||
* @apiSuccess (Success 200) {Number} alarm.quantity Quantity of units
|
||||
* @apiSuccess (Success 200) {String} alarm.unit Either MINUTES, HOURS, or DAYS
|
||||
* @apiSuccess (Success 200) {String} alarm.reference Either BEFORE or AFTER
|
||||
* @apiSuccess (Success 200) {String} alarm.relation Either START or END
|
||||
|
@ -634,9 +615,9 @@
|
|||
* @apiSuccess (Success 200) {Number} repeat.interval Intervals the recurrence rule repeats
|
||||
* @apiSuccess (Success 200) {String} [repeat.count] Number of occurrences at which to range-bound the recurrence
|
||||
* @apiSuccess (Success 200) {String} [repeat.until] A Unix epoch value that bounds the recurrence rule in an inclusive manner
|
||||
* @apiSuccess (Success 200) {Number[]} [repeat.days] List of days of the week
|
||||
* @apiSuccess (Success 200) {Object[]} [repeat.days] List of days of the week (by day mask)
|
||||
* @apiSuccess (Success 200) {String} repeat.days.day Day of the week (SU, MO, TU, WE, TH, FR, SA)
|
||||
* @apiSuccess (Success 200) {Number} [repeat.days.occurence] Occurrence of a specific day within the monthly or yearly rule (valures are -5 to 5)
|
||||
* @apiSuccess (Success 200) {Number} [repeat.days.occurence] Occurrence of a specific day within the monthly or yearly rule (values are -5 to 5)
|
||||
* @apiSuccess (Success 200) {Number[]} [repeat.months] List of months of the year (values are 1 to 12)
|
||||
* @apiSuccess (Success 200) {Number[]} [repeat.monthdays] Days of the month (values are 1 to 31)
|
||||
*/
|
||||
|
@ -648,11 +629,14 @@
|
|||
SOGoUserDefaults *ud;
|
||||
SOGoCalendarComponent *co;
|
||||
iCalAlarm *anAlarm;
|
||||
iCalEvent *event;
|
||||
|
||||
BOOL resetAlarm;
|
||||
unsigned int snoozeAlarm;
|
||||
|
||||
[self event];
|
||||
// [self component];
|
||||
// [self componentCalendar];
|
||||
event = [self event];
|
||||
|
||||
ud = [[context activeUser] userDefaults];
|
||||
timeZone = [ud timeZone];
|
||||
|
@ -661,14 +645,6 @@
|
|||
[eventStartDate setTimeZone: timeZone];
|
||||
[eventEndDate setTimeZone: timeZone];
|
||||
co = [self clientObject];
|
||||
|
||||
if (!componentCalendar)
|
||||
{
|
||||
componentCalendar = [co container];
|
||||
if ([componentCalendar isKindOfClass: [SOGoCalendarComponent class]])
|
||||
componentCalendar = [componentCalendar container];
|
||||
[componentCalendar retain];
|
||||
}
|
||||
|
||||
// resetAlarm=yes is set only when we are about to show the alarm popup in the Web
|
||||
// interface of SOGo. See generic.js for details. snoozeAlarm=X is called when the
|
||||
|
@ -676,7 +652,7 @@
|
|||
// If either is set, we must find the right alarm.
|
||||
resetAlarm = [[[context request] formValueForKey: @"resetAlarm"] boolValue];
|
||||
snoozeAlarm = [[[context request] formValueForKey: @"snoozeAlarm"] intValue];
|
||||
|
||||
|
||||
if (resetAlarm || snoozeAlarm)
|
||||
{
|
||||
iCalEvent *master;
|
||||
|
@ -686,7 +662,7 @@
|
|||
timezone: timeZone
|
||||
startDate: &eventStartDate
|
||||
endDate: &eventEndDate];
|
||||
|
||||
|
||||
anAlarm = [event firstDisplayOrAudioAlarm];
|
||||
|
||||
if (resetAlarm)
|
||||
|
@ -694,7 +670,7 @@
|
|||
iCalTrigger *aTrigger;
|
||||
|
||||
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)
|
||||
|
@ -707,10 +683,10 @@
|
|||
[co nameInContainer], @"id",
|
||||
[componentCalendar nameInContainer], @"pid",
|
||||
[componentCalendar displayName], @"calendar",
|
||||
[self formattedDateString: eventStartDate], @"startDate",
|
||||
[self _dateString: eventStartDate], @"startDate",
|
||||
[dateFormatter formattedDate: eventStartDate], @"localizedStartDate",
|
||||
[dateFormatter formattedTime: eventStartDate], @"startTime",
|
||||
[self formattedDateString: eventEndDate], @"endDate",
|
||||
[self _dateString: eventEndDate], @"endDate",
|
||||
[dateFormatter formattedDate: eventEndDate], @"localizedEndDate",
|
||||
[dateFormatter formattedTime: eventEndDate], @"endTime",
|
||||
nil];
|
||||
|
@ -722,78 +698,4 @@
|
|||
return [self responseWithStatus: 200 andJSONRepresentation: data];
|
||||
}
|
||||
|
||||
- (void) takeValuesFromRequest: (WORequest *) _rq
|
||||
inContext: (WOContext *) _ctx
|
||||
{
|
||||
int nbrDays;
|
||||
iCalDateTime *startDate;
|
||||
iCalTimeZone *tz;
|
||||
NSCalendarDate *allDayStartDate;
|
||||
NSTimeZone *timeZone;
|
||||
SOGoUserDefaults *ud;
|
||||
signed int offset;
|
||||
id o;
|
||||
|
||||
[self event];
|
||||
[super takeValuesFromRequest: _rq inContext: _ctx];
|
||||
|
||||
if (isAllDay)
|
||||
{
|
||||
nbrDays = ((float) abs ([aptEndDate timeIntervalSinceDate: aptStartDate])
|
||||
/ 86400) + 1;
|
||||
// Convert all-day start date to GMT (floating date)
|
||||
ud = [[context activeUser] userDefaults];
|
||||
timeZone = [ud timeZone];
|
||||
offset = [timeZone secondsFromGMTForDate: aptStartDate];
|
||||
allDayStartDate = [aptStartDate dateByAddingYears:0 months:0 days:0 hours:0 minutes:0
|
||||
seconds:offset];
|
||||
[event setAllDayWithStartDate: allDayStartDate
|
||||
duration: nbrDays];
|
||||
}
|
||||
else
|
||||
{
|
||||
[event setStartDate: aptStartDate];
|
||||
[event setEndDate: aptEndDate];
|
||||
}
|
||||
|
||||
if (!isAllDay)
|
||||
{
|
||||
// Make sure there's a vTimeZone associated to the event unless it
|
||||
// is an all-day event.
|
||||
startDate = (iCalDateTime *)[event uniqueChildWithTag: @"dtstart"];
|
||||
if (![startDate timeZone])
|
||||
{
|
||||
ud = [[context activeUser] userDefaults];
|
||||
tz = [iCalTimeZone timeZoneForName: [ud timeZoneName]];
|
||||
if ([[event parent] addTimeZone: tz])
|
||||
{
|
||||
[startDate setTimeZone: tz];
|
||||
[(iCalDateTime *)[event uniqueChildWithTag: @"dtend"] setTimeZone: tz];
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (![[self clientObject] isNew])
|
||||
{
|
||||
// Remove the vTimeZone when dealing with an all-day event.
|
||||
startDate = (iCalDateTime *)[event uniqueChildWithTag: @"dtstart"];
|
||||
tz = [startDate timeZone];
|
||||
if (tz)
|
||||
{
|
||||
[startDate setTimeZone: nil];
|
||||
[(iCalDateTime *)[event uniqueChildWithTag: @"dtend"] setTimeZone: nil];
|
||||
[[event parent] removeChild: tz];
|
||||
}
|
||||
}
|
||||
|
||||
[event setTransparency: (isTransparent? @"TRANSPARENT" : @"OPAQUE")];
|
||||
|
||||
o = [event firstChildWithTag: @"X-SOGo-Send-Appointment-Notifications"];
|
||||
|
||||
if (!sendAppointmentNotifications && !o)
|
||||
[event addChild: [CardElement simpleElementWithTag: @"X-SOGo-Send-Appointment-Notifications" value: @"NO"]];
|
||||
else if (sendAppointmentNotifications && o)
|
||||
[event removeChild: o];
|
||||
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -23,167 +23,17 @@
|
|||
|
||||
#import <SOGoUI/UIxComponent.h>
|
||||
|
||||
@class NSArray;
|
||||
@class NSCalendarDate;
|
||||
@class NSDictionary;
|
||||
@class NSString;
|
||||
|
||||
@class iCalPerson;
|
||||
@class iCalRecurrenceRule;
|
||||
@class iCalRepeatableEntityObject;
|
||||
|
||||
@interface UIxComponentEditor : UIxComponent
|
||||
{
|
||||
iCalRepeatableEntityObject *component;
|
||||
id item;
|
||||
id attendee;
|
||||
|
||||
NSString *rsvpURL;
|
||||
NSString *saveURL;
|
||||
NSMutableArray *calendarList;
|
||||
NSDictionary *organizerProfile;
|
||||
|
||||
/* individual values */
|
||||
NSCalendarDate *cycleUntilDate;
|
||||
NSString *title;
|
||||
NSString *location;
|
||||
SOGoAppointmentFolder *componentCalendar;
|
||||
NSString *comment;
|
||||
NSString *attachUrl;
|
||||
NSString *priority;
|
||||
NSString *classification;
|
||||
NSString *status;
|
||||
NSString *category;
|
||||
NSArray *categories;
|
||||
NSDictionary *cycle;
|
||||
NSString *cycleEnd;
|
||||
iCalPerson *organizer;
|
||||
iCalPerson *ownerAsAttendee;
|
||||
NSString *componentOwner;
|
||||
NSString *dateFormat;
|
||||
|
||||
NSMutableDictionary *jsonAttendees;
|
||||
|
||||
NSString *reminder;
|
||||
NSString *reminderQuantity;
|
||||
NSString *reminderUnit;
|
||||
NSString *reminderRelation;
|
||||
NSString *reminderReference;
|
||||
NSString *reminderAction;
|
||||
BOOL reminderEmailOrganizer;
|
||||
BOOL reminderEmailAttendees;
|
||||
|
||||
/* ugly */
|
||||
NSString *repeat;
|
||||
|
||||
NSString *repeatType;
|
||||
NSString *repeat1;
|
||||
NSString *repeat2;
|
||||
NSString *repeat3;
|
||||
NSString *repeat4;
|
||||
NSString *repeat5;
|
||||
NSString *repeat6;
|
||||
NSString *repeat7;
|
||||
|
||||
NSString *range1;
|
||||
NSString *range2;
|
||||
}
|
||||
|
||||
- (NSString *) toolbar;
|
||||
- (void) setComponent: (iCalRepeatableEntityObject *) newComponent;
|
||||
|
||||
- (void) setSaveURL: (NSString *) newSaveURL;
|
||||
- (NSString *) saveURL;
|
||||
|
||||
- (void) setItem: (id) _item;
|
||||
- (id) item;
|
||||
|
||||
- (SOGoAppointmentFolder *) componentCalendar;
|
||||
|
||||
- (NSArray *) calendarList;
|
||||
- (NSString *) calendarsFoldersList;
|
||||
- (NSString *) calendarDisplayName;
|
||||
|
||||
- (SOGoAppointmentFolder *) componentCalendar;
|
||||
- (void) setComponentCalendar: (SOGoAppointmentFolder *) _componentCalendar;
|
||||
|
||||
- (NSArray *) categoryList;
|
||||
- (void) setCategories: (NSArray *) _categories;
|
||||
- (NSArray *) categories;
|
||||
|
||||
- (NSArray *) priorities;
|
||||
- (void) setPriority: (NSString *) _priority;
|
||||
- (NSString *) priority;
|
||||
- (NSString *) itemPriorityText;
|
||||
|
||||
- (NSArray *) classificationClasses;
|
||||
- (void) setClassification: (NSString *) _classification;
|
||||
- (NSString *) classification;
|
||||
- (NSString *) itemClassificationText;
|
||||
|
||||
- (void) setStatus: (NSString *) _status;
|
||||
- (NSString *) status;
|
||||
- (NSString *) itemStatusText;
|
||||
|
||||
- (void) setTitle: (NSString *) _value;
|
||||
- (NSString *) title;
|
||||
|
||||
- (void) setLocation: (NSString *) _value;
|
||||
- (NSString *) location;
|
||||
|
||||
- (NSString *) location;
|
||||
|
||||
- (void) setComment: (NSString *) _value;
|
||||
- (NSString *) comment;
|
||||
|
||||
- (void) setAttach: (NSString *) _attachUrl;
|
||||
- (NSString *) attach;
|
||||
|
||||
- (BOOL) hasAttendees;
|
||||
- (BOOL) hasCreatedBy;
|
||||
- (NSString *) createdBy;
|
||||
- (NSString *) createdByLink;
|
||||
- (NSString *) createdByName;
|
||||
|
||||
- (NSString *) jsonAttendees;
|
||||
|
||||
- (NSString *) repeat;
|
||||
- (void) setRepeat: (NSString *) newRepeat;
|
||||
|
||||
- (NSString *) reminder;
|
||||
- (void) setReminder: (NSString *) newReminder;
|
||||
|
||||
////////////////////////////////// JUNK ////////////////////////////////////////
|
||||
////////////////////////////////// JUNK ////////////////////////////////////////
|
||||
////////////////////////////////// JUNK ////////////////////////////////////////
|
||||
- (NSArray *) cycles;
|
||||
- (void) setCycle: (NSDictionary *) _cycle;
|
||||
- (NSDictionary *) cycle;
|
||||
- (BOOL) hasCycle;
|
||||
- (NSString *) cycleLabel;
|
||||
- (void) setCycleUntilDate: (NSCalendarDate *) _cycleUntilDate;
|
||||
- (NSCalendarDate *) cycleUntilDate;
|
||||
- (iCalRecurrenceRule *) rrule;
|
||||
- (void) adjustCycleControlsForRRule: (iCalRecurrenceRule *) _rrule;
|
||||
- (NSDictionary *) cycleMatchingRRule: (iCalRecurrenceRule *) _rrule;
|
||||
- (NSArray *) cycleEnds;
|
||||
- (void) setCycleEnd: (NSString *) _cycleEnd;
|
||||
- (NSString *) cycleEnd;
|
||||
- (BOOL) isCycleEndUntil;
|
||||
- (void) setIsCycleEndUntil;
|
||||
- (void) setIsCycleEndNever;
|
||||
////////////////////////////////// JUNK ////////////////////////////////////////
|
||||
////////////////////////////////// JUNK ////////////////////////////////////////
|
||||
////////////////////////////////// JUNK ////////////////////////////////////////
|
||||
|
||||
/* access */
|
||||
- (BOOL) canEditComponent;
|
||||
- (unsigned int) firstDayOfWeek;
|
||||
|
||||
/* helpers */
|
||||
- (NSString *) completeURIForMethod: (NSString *) _method;
|
||||
- (BOOL) isWriteableClientObject;
|
||||
- (NSException *) validateObjectForStatusChange;
|
||||
- (void) setAttributes: (NSDictionary *) attributes;
|
||||
|
||||
+ (NSArray *) reminderValues;
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue