Monotone-Parent: 29948ba19f24f47aa6c1b2c0764586b89ff9493f
Monotone-Revision: 1a5434f30282a4932bf29227da4cf2da44ef5783 Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2008-07-11T22:28:12 Monotone-Branch: ca.inverse.sogomaint-2.0.2
parent
45f0686d92
commit
6c5003d7bc
14
ChangeLog
14
ChangeLog
|
@ -1,3 +1,17 @@
|
||||||
|
2008-07-11 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||||
|
|
||||||
|
* SoObjects/Appointments/SOGoAppointmentFolder.m
|
||||||
|
([SOGoAppointmentFolder
|
||||||
|
-fetchFields:_fieldsfrom:_startDateto:_endDatetitle:titlecomponent:_componentadditionalFilters:filters]):
|
||||||
|
take exceptional modifications into account.
|
||||||
|
|
||||||
|
* SoObjects/Appointments/iCalToDo+SOGo.m: new class module with
|
||||||
|
category methods for iCalToDo.
|
||||||
|
([iCalToDo -quickRecord]): same as for method below.
|
||||||
|
|
||||||
|
* SoObjects/Appointments/iCalEvent+SOGo.m ([iCalEvent
|
||||||
|
-quickRecord]): new method taken from OCSiCalFieldExtractor.
|
||||||
|
|
||||||
2008-07-10 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
2008-07-10 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||||
|
|
||||||
* SoObjects/SOGo/NSString+DAV.m ([NSString -asWebDAVTuple]): new
|
* SoObjects/SOGo/NSString+DAV.m ([NSString -asWebDAVTuple]): new
|
||||||
|
|
|
@ -17,9 +17,6 @@ ADDITIONAL_INCLUDE_DIRS += -I../SOPE
|
||||||
ADDITIONAL_LIB_DIRS += -L../SOPE/GDLContentStore/obj
|
ADDITIONAL_LIB_DIRS += -L../SOPE/GDLContentStore/obj
|
||||||
|
|
||||||
libOGoContentStore_OBJC_FILES += \
|
libOGoContentStore_OBJC_FILES += \
|
||||||
iCalEntityObject+OCS.m \
|
|
||||||
iCalRepeatableEntityObject+OCS.m \
|
|
||||||
\
|
|
||||||
OCSiCalFieldExtractor.m \
|
OCSiCalFieldExtractor.m \
|
||||||
OCSContactFieldExtractor.m \
|
OCSContactFieldExtractor.m \
|
||||||
|
|
||||||
|
|
|
@ -19,34 +19,21 @@
|
||||||
02111-1307, USA.
|
02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#import <Foundation/NSArray.h>
|
||||||
#import <Foundation/NSCalendarDate.h>
|
#import <Foundation/NSCalendarDate.h>
|
||||||
#import <Foundation/NSNull.h>
|
#import <Foundation/NSDictionary.h>
|
||||||
#import <Foundation/NSString.h>
|
#import <Foundation/NSString.h>
|
||||||
#import <Foundation/NSValue.h>
|
|
||||||
|
|
||||||
#import <NGExtensions/NSNull+misc.h>
|
#import <NGExtensions/NSNull+misc.h>
|
||||||
#import <NGExtensions/NSObject+Logs.h>
|
#import <NGExtensions/NSObject+Logs.h>
|
||||||
|
#import <NGCards/iCalCalendar.h>
|
||||||
|
|
||||||
#import "iCalEntityObject+OCS.h"
|
#import <SoObjects/Appointments/iCalRepeatableEntityObject+SOGo.h>
|
||||||
#import "iCalRepeatableEntityObject+OCS.h"
|
|
||||||
|
|
||||||
#import "OCSiCalFieldExtractor.h"
|
#import "OCSiCalFieldExtractor.h"
|
||||||
|
|
||||||
@implementation OCSiCalFieldExtractor
|
@implementation OCSiCalFieldExtractor
|
||||||
|
|
||||||
static NSCalendarDate *distantFuture = nil;
|
|
||||||
static NSNumber *distantFutureNumber = nil;
|
|
||||||
|
|
||||||
+ (void) initialize
|
|
||||||
{
|
|
||||||
if (!distantFuture)
|
|
||||||
{
|
|
||||||
distantFuture = [[NSCalendarDate distantFuture] retain];
|
|
||||||
/* INT_MAX due to Postgres constraint */
|
|
||||||
distantFutureNumber = [[NSNumber numberWithUnsignedInt: INT_MAX] retain];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (id) sharedICalFieldExtractor
|
+ (id) sharedICalFieldExtractor
|
||||||
{
|
{
|
||||||
static OCSiCalFieldExtractor *extractor = nil;
|
static OCSiCalFieldExtractor *extractor = nil;
|
||||||
|
@ -59,287 +46,6 @@ static NSNumber *distantFutureNumber = nil;
|
||||||
|
|
||||||
/* operations */
|
/* operations */
|
||||||
|
|
||||||
- (NSNumber *) numberForDate: (NSCalendarDate *) _date
|
|
||||||
{
|
|
||||||
return ((_date == distantFuture)
|
|
||||||
? distantFutureNumber
|
|
||||||
: [NSNumber numberWithUnsignedInt: [_date timeIntervalSince1970]]);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSMutableDictionary *) extractQuickFieldsFromEvent: (iCalEvent *) _event
|
|
||||||
{
|
|
||||||
NSMutableDictionary *row;
|
|
||||||
NSCalendarDate *startDate, *endDate;
|
|
||||||
NSArray *attendees;
|
|
||||||
NSString *uid, *title, *location, *status;
|
|
||||||
NSNumber *sequence, *dateNumber;
|
|
||||||
id organizer;
|
|
||||||
id participants, partmails;
|
|
||||||
NSMutableString *partstates;
|
|
||||||
unsigned int i, count;
|
|
||||||
BOOL isAllDay;
|
|
||||||
iCalAccessClass accessClass;
|
|
||||||
|
|
||||||
if (_event == nil)
|
|
||||||
return nil;
|
|
||||||
|
|
||||||
/* extract values */
|
|
||||||
|
|
||||||
startDate = [_event startDate];
|
|
||||||
endDate = [_event endDate];
|
|
||||||
uid = [_event uid];
|
|
||||||
title = [_event summary];
|
|
||||||
if (![title isNotNull])
|
|
||||||
title = @"";
|
|
||||||
location = [_event location];
|
|
||||||
sequence = [_event sequence];
|
|
||||||
accessClass = [_event symbolicAccessClass];
|
|
||||||
isAllDay = [_event isAllDay];
|
|
||||||
status = [[_event status] uppercaseString];
|
|
||||||
|
|
||||||
attendees = [_event attendees];
|
|
||||||
partmails = [attendees valueForKey: @"rfc822Email"];
|
|
||||||
partmails = [partmails componentsJoinedByString: @"\n"];
|
|
||||||
participants = [attendees valueForKey: @"cn"];
|
|
||||||
participants = [participants componentsJoinedByString: @"\n"];
|
|
||||||
|
|
||||||
/* build row */
|
|
||||||
|
|
||||||
row = [NSMutableDictionary dictionaryWithCapacity:8];
|
|
||||||
|
|
||||||
[row setObject: @"vevent" forKey: @"c_component"];
|
|
||||||
|
|
||||||
if ([uid isNotNull])
|
|
||||||
[row setObject:uid forKey: @"c_uid"];
|
|
||||||
else
|
|
||||||
[self logWithFormat: @"WARNING: could not extract a uid from event!"];
|
|
||||||
|
|
||||||
|
|
||||||
[row setObject: [NSNumber numberWithBool: isAllDay]
|
|
||||||
forKey: @"c_isallday"];
|
|
||||||
[row setObject: [NSNumber numberWithBool: [_event isRecurrent]]
|
|
||||||
forKey: @"c_iscycle"];
|
|
||||||
[row setObject: [NSNumber numberWithBool: [_event isOpaque]]
|
|
||||||
forKey: @"c_isopaque"];
|
|
||||||
[row setObject: [NSNumber numberWithInt: [_event priorityNumber]]
|
|
||||||
forKey: @"c_priority"];
|
|
||||||
|
|
||||||
[row setObject: title forKey: @"c_title"];
|
|
||||||
if ([location isNotNull]) [row setObject: location forKey: @"c_location"];
|
|
||||||
if ([sequence isNotNull]) [row setObject: sequence forKey: @"c_sequence"];
|
|
||||||
|
|
||||||
if ([startDate isNotNull])
|
|
||||||
[row setObject: [self numberForDate: startDate]
|
|
||||||
forKey: @"c_startdate"];
|
|
||||||
if ([endDate isNotNull])
|
|
||||||
{
|
|
||||||
if (endDate == distantFuture)
|
|
||||||
dateNumber = distantFutureNumber;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (isAllDay)
|
|
||||||
i = 1;
|
|
||||||
else
|
|
||||||
i = 0;
|
|
||||||
dateNumber
|
|
||||||
= [NSNumber numberWithUnsignedInt:
|
|
||||||
[endDate timeIntervalSince1970] - i];
|
|
||||||
}
|
|
||||||
[row setObject: dateNumber forKey: @"c_enddate"];
|
|
||||||
}
|
|
||||||
|
|
||||||
if ([_event isRecurrent]) {
|
|
||||||
NSCalendarDate *date;
|
|
||||||
|
|
||||||
date = [_event lastPossibleRecurrenceStartDate];
|
|
||||||
if (!date) {
|
|
||||||
/* this could also be *nil*, but in the end it makes the fetchspecs
|
|
||||||
more complex - thus we set it to a "reasonable" distant future */
|
|
||||||
date = distantFuture;
|
|
||||||
}
|
|
||||||
[row setObject:[self numberForDate:date] forKey: @"c_cycleenddate"];
|
|
||||||
[row setObject:[_event cycleInfo] forKey: @"c_cycleinfo"];
|
|
||||||
}
|
|
||||||
|
|
||||||
if ([participants length] > 0)
|
|
||||||
[row setObject: participants forKey: @"c_participants"];
|
|
||||||
if ([partmails length] > 0)
|
|
||||||
[row setObject: partmails forKey: @"c_partmails"];
|
|
||||||
|
|
||||||
if ([status isNotNull]) {
|
|
||||||
int code = 1;
|
|
||||||
|
|
||||||
if ([status isEqualToString: @"TENTATIVE"])
|
|
||||||
code = 2;
|
|
||||||
else if ([status isEqualToString: @"CANCELLED"])
|
|
||||||
code = 0;
|
|
||||||
[row setObject:[NSNumber numberWithInt:code] forKey: @"c_status"];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* confirmed by default */
|
|
||||||
[row setObject: [NSNumber numberWithInt:1] forKey: @"c_status"];
|
|
||||||
}
|
|
||||||
|
|
||||||
[row setObject: [NSNumber numberWithUnsignedInt: accessClass]
|
|
||||||
forKey: @"c_classification"];
|
|
||||||
|
|
||||||
organizer = [_event organizer];
|
|
||||||
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];
|
|
||||||
for ( i = 0; i < count; i++) {
|
|
||||||
iCalPerson *p;
|
|
||||||
iCalPersonPartStat stat;
|
|
||||||
|
|
||||||
p = [attendees objectAtIndex:i];
|
|
||||||
stat = [p participationStatus];
|
|
||||||
if(i != 0)
|
|
||||||
[partstates appendString: @"\n"];
|
|
||||||
[partstates appendFormat: @"%d", stat];
|
|
||||||
}
|
|
||||||
[row setObject:partstates forKey: @"c_partstates"];
|
|
||||||
[partstates release];
|
|
||||||
return row;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSMutableDictionary *) extractQuickFieldsFromTodo: (iCalToDo *) _task
|
|
||||||
{
|
|
||||||
NSMutableDictionary *row;
|
|
||||||
NSCalendarDate *startDate, *dueDate;
|
|
||||||
NSArray *attendees;
|
|
||||||
NSString *uid, *title, *location, *status;
|
|
||||||
NSNumber *sequence;
|
|
||||||
id organizer, date;
|
|
||||||
id participants, partmails;
|
|
||||||
NSMutableString *partstates;
|
|
||||||
unsigned i, count, code;
|
|
||||||
iCalAccessClass accessClass;
|
|
||||||
|
|
||||||
if (_task == nil)
|
|
||||||
return nil;
|
|
||||||
|
|
||||||
/* extract values */
|
|
||||||
|
|
||||||
startDate = [_task startDate];
|
|
||||||
dueDate = [_task due];
|
|
||||||
uid = [_task uid];
|
|
||||||
title = [_task summary];
|
|
||||||
if (![title isNotNull])
|
|
||||||
title = @"";
|
|
||||||
location = [_task location];
|
|
||||||
sequence = [_task sequence];
|
|
||||||
accessClass = [_task symbolicAccessClass];
|
|
||||||
status = [[_task status] uppercaseString];
|
|
||||||
|
|
||||||
attendees = [_task attendees];
|
|
||||||
partmails = [attendees valueForKey: @"rfc822Email"];
|
|
||||||
partmails = [partmails componentsJoinedByString: @"\n"];
|
|
||||||
participants = [attendees valueForKey: @"cn"];
|
|
||||||
participants = [participants componentsJoinedByString: @"\n"];
|
|
||||||
|
|
||||||
/* build row */
|
|
||||||
|
|
||||||
row = [NSMutableDictionary dictionaryWithCapacity:8];
|
|
||||||
|
|
||||||
[row setObject: @"vtodo" forKey: @"c_component"];
|
|
||||||
|
|
||||||
if ([uid isNotNull])
|
|
||||||
[row setObject:uid forKey: @"c_uid"];
|
|
||||||
else
|
|
||||||
[self logWithFormat: @"WARNING: could not extract a uid from event!"];
|
|
||||||
|
|
||||||
[row setObject:[NSNumber numberWithBool:[_task isRecurrent]]
|
|
||||||
forKey: @"c_iscycle"];
|
|
||||||
[row setObject:[NSNumber numberWithInt:[_task priorityNumber]]
|
|
||||||
forKey: @"c_priority"];
|
|
||||||
|
|
||||||
[row setObject: [NSNumber numberWithBool: NO]
|
|
||||||
forKey: @"c_isallday"];
|
|
||||||
[row setObject: [NSNumber numberWithBool: NO]
|
|
||||||
forKey: @"c_isopaque"];
|
|
||||||
|
|
||||||
[row setObject: title forKey: @"c_title"];
|
|
||||||
if ([location isNotNull]) [row setObject: location forKey: @"c_location"];
|
|
||||||
if ([sequence isNotNull]) [row setObject: sequence forKey: @"c_sequence"];
|
|
||||||
|
|
||||||
if ([startDate isNotNull])
|
|
||||||
date = [self numberForDate: startDate];
|
|
||||||
else
|
|
||||||
date = [NSNull null];
|
|
||||||
[row setObject: date forKey: @"c_startdate"];
|
|
||||||
|
|
||||||
if ([dueDate isNotNull])
|
|
||||||
date = [self numberForDate: dueDate];
|
|
||||||
else
|
|
||||||
date = [NSNull null];
|
|
||||||
[row setObject: date forKey: @"c_enddate"];
|
|
||||||
|
|
||||||
if ([_task isRecurrent])
|
|
||||||
{
|
|
||||||
[row setObject: [self numberForDate: distantFuture]
|
|
||||||
forKey: @"c_cycleenddate"];
|
|
||||||
[row setObject: [_task cycleInfo]
|
|
||||||
forKey: @"c_cycleinfo"];
|
|
||||||
}
|
|
||||||
|
|
||||||
if ([participants length] > 0)
|
|
||||||
[row setObject:participants forKey: @"c_participants"];
|
|
||||||
if ([partmails length] > 0)
|
|
||||||
[row setObject:partmails forKey: @"c_partmails"];
|
|
||||||
|
|
||||||
if ([status isNotNull]) {
|
|
||||||
code = 0; /* NEEDS-ACTION */
|
|
||||||
if ([status isEqualToString: @"COMPLETED"])
|
|
||||||
code = 1;
|
|
||||||
else if ([status isEqualToString: @"IN-PROCESS"])
|
|
||||||
code = 2;
|
|
||||||
else if ([status isEqualToString: @"CANCELLED"])
|
|
||||||
code = 3;
|
|
||||||
[row setObject: [NSNumber numberWithInt: code] forKey: @"c_status"];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* confirmed by default */
|
|
||||||
[row setObject:[NSNumber numberWithInt:1] forKey: @"c_status"];
|
|
||||||
}
|
|
||||||
|
|
||||||
[row setObject: [NSNumber numberWithUnsignedInt: accessClass]
|
|
||||||
forKey: @"c_classification"];
|
|
||||||
|
|
||||||
organizer = [_task organizer];
|
|
||||||
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];
|
|
||||||
for ( i = 0; i < count; i++) {
|
|
||||||
iCalPerson *p;
|
|
||||||
iCalPersonPartStat stat;
|
|
||||||
|
|
||||||
p = [attendees objectAtIndex:i];
|
|
||||||
stat = [p participationStatus];
|
|
||||||
if(i != 0)
|
|
||||||
[partstates appendString: @"\n"];
|
|
||||||
[partstates appendFormat: @"%d", stat];
|
|
||||||
}
|
|
||||||
[row setObject:partstates forKey: @"c_partstates"];
|
|
||||||
[partstates release];
|
|
||||||
return row;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (CardGroup *) firstElementFromCalendar: (iCalCalendar *) ical
|
- (CardGroup *) firstElementFromCalendar: (iCalCalendar *) ical
|
||||||
{
|
{
|
||||||
NSArray *elements;
|
NSArray *elements;
|
||||||
|
@ -349,13 +55,7 @@ static NSNumber *distantFutureNumber = nil;
|
||||||
elements = [ical allObjects];
|
elements = [ical allObjects];
|
||||||
count = [elements count];
|
count = [elements count];
|
||||||
if (count)
|
if (count)
|
||||||
{
|
element = [elements objectAtIndex: 0];
|
||||||
if (count > 1)
|
|
||||||
[self logWithFormat:
|
|
||||||
@"WARNING: given calendar contains more than one event: %@",
|
|
||||||
ical];
|
|
||||||
element = [elements objectAtIndex: 0];
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
[self logWithFormat: @"ERROR: given calendar contains no elements: %@", ical];
|
[self logWithFormat: @"ERROR: given calendar contains no elements: %@", ical];
|
||||||
|
@ -365,34 +65,32 @@ static NSNumber *distantFutureNumber = nil;
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSMutableDictionary *)extractQuickFieldsFromContent:(NSString *)_content {
|
- (NSMutableDictionary *) extractQuickFieldsFromContent: (NSString *) _content
|
||||||
NSDictionary *fields;
|
{
|
||||||
|
NSMutableDictionary *fields;
|
||||||
id cal;
|
id cal;
|
||||||
|
|
||||||
if ([_content length] == 0)
|
|
||||||
return nil;
|
|
||||||
|
|
||||||
cal = [iCalCalendar parseSingleFromSource: _content];
|
|
||||||
|
|
||||||
fields = nil;
|
fields = nil;
|
||||||
if (cal)
|
|
||||||
|
if ([_content length])
|
||||||
{
|
{
|
||||||
if ([cal isKindOfClass:[iCalCalendar class]])
|
cal = [iCalCalendar parseSingleFromSource: _content];
|
||||||
cal = [self firstElementFromCalendar: cal];
|
if (cal)
|
||||||
|
{
|
||||||
|
if ([cal isKindOfClass: [iCalCalendar class]])
|
||||||
|
cal = [self firstElementFromCalendar: cal];
|
||||||
|
|
||||||
if ([cal isKindOfClass:[iCalEvent class]])
|
if ([cal isKindOfClass: [iCalRepeatableEntityObject class]])
|
||||||
fields = [[self extractQuickFieldsFromEvent:cal] retain];
|
fields = [cal quickRecord];
|
||||||
else if ([cal isKindOfClass:[iCalToDo class]])
|
else if ([cal isNotNull])
|
||||||
fields = [[self extractQuickFieldsFromTodo:cal] retain];
|
[self logWithFormat: @"ERROR: unexpected iCalendar parse result: %@",
|
||||||
else if ([cal isNotNull]) {
|
cal];
|
||||||
[self logWithFormat: @"ERROR: unexpected iCalendar parse result: %@",
|
}
|
||||||
cal];
|
else
|
||||||
}
|
[self logWithFormat: @"ERROR: parsing source didn't return anything"];
|
||||||
}
|
}
|
||||||
else
|
|
||||||
[self logWithFormat: @"ERROR: parsing source didn't return anything"];
|
|
||||||
|
|
||||||
return [fields autorelease];
|
return fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
@end /* OCSiCalFieldExtractor */
|
@end /* OCSiCalFieldExtractor */
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2004-2005 SKYRIX Software AG
|
|
||||||
|
|
||||||
This file is part of OpenGroupware.org.
|
|
||||||
|
|
||||||
OGo is free software; you can redistribute it and/or modify it under
|
|
||||||
the terms of the GNU Lesser General Public License as published by the
|
|
||||||
Free Software Foundation; either version 2, or (at your option) any
|
|
||||||
later version.
|
|
||||||
|
|
||||||
OGo is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
|
||||||
License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with OGo; see the file COPYING. If not, write to the
|
|
||||||
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|
||||||
02111-1307, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __OGoContentStore_iCalEntityObject_OCS_H_
|
|
||||||
#define __OGoContentStore_iCalEntityObject_OCS_H_
|
|
||||||
|
|
||||||
#include <NGCards/NGCards.h>
|
|
||||||
|
|
||||||
@interface iCalEntityObject (OCS)
|
|
||||||
|
|
||||||
- (int)priorityNumber;
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
#endif /* __OGoContentStore_iCalEntityObject_OCS_H_ */
|
|
|
@ -1,42 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (C) 2004-2005 SKYRIX Software AG
|
|
||||||
|
|
||||||
This file is part of OpenGroupware.org.
|
|
||||||
|
|
||||||
OGo is free software; you can redistribute it and/or modify it under
|
|
||||||
the terms of the GNU Lesser General Public License as published by the
|
|
||||||
Free Software Foundation; either version 2, or (at your option) any
|
|
||||||
later version.
|
|
||||||
|
|
||||||
OGo is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
|
||||||
License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU Lesser General Public
|
|
||||||
License along with OGo; see the file COPYING. If not, write to the
|
|
||||||
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|
||||||
02111-1307, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#import "iCalEntityObject+OCS.h"
|
|
||||||
|
|
||||||
@implementation iCalEntityObject (OCS)
|
|
||||||
|
|
||||||
- (int)priorityNumber {
|
|
||||||
NSString *prio;
|
|
||||||
|
|
||||||
prio = [self priority];
|
|
||||||
if(prio) {
|
|
||||||
NSRange r;
|
|
||||||
|
|
||||||
r = [prio rangeOfString:@";"];
|
|
||||||
if(r.length > 0) {
|
|
||||||
prio = [prio substringToIndex:r.location];
|
|
||||||
}
|
|
||||||
return [prio intValue];
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
|
@ -26,59 +26,4 @@
|
||||||
|
|
||||||
@implementation iCalRepeatableEntityObject (OCS)
|
@implementation iCalRepeatableEntityObject (OCS)
|
||||||
|
|
||||||
- (NSArray *) _indexedRules: (NSArray *) rules
|
|
||||||
{
|
|
||||||
NSMutableArray *ma;
|
|
||||||
unsigned int i, count;
|
|
||||||
NSString *valuesString;
|
|
||||||
|
|
||||||
ma = nil;
|
|
||||||
count = [rules count];
|
|
||||||
if (count > 0)
|
|
||||||
{
|
|
||||||
ma = [NSMutableArray arrayWithCapacity:count];
|
|
||||||
for (i = 0; i < count; i++)
|
|
||||||
{
|
|
||||||
iCalRecurrenceRule *rule;
|
|
||||||
|
|
||||||
rule = [rules objectAtIndex:i];
|
|
||||||
#warning we could return an NSArray instead and feed it as such to the iCalRecurrenceRule in SOGoAppointmentFolder...
|
|
||||||
valuesString = [[rule values] componentsJoinedByString: @";"];
|
|
||||||
[ma addObject: valuesString];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ma;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSString *) cycleInfo
|
|
||||||
{
|
|
||||||
NSArray *rules;
|
|
||||||
NSString *value;
|
|
||||||
NSMutableDictionary *cycleInfo;
|
|
||||||
|
|
||||||
if ([self isRecurrent])
|
|
||||||
{
|
|
||||||
cycleInfo = [NSMutableDictionary dictionaryWithCapacity: 3];
|
|
||||||
|
|
||||||
/* rules */
|
|
||||||
rules = [self _indexedRules: [self recurrenceRules]];
|
|
||||||
if (rules)
|
|
||||||
[cycleInfo setObject: rules forKey: @"rules"];
|
|
||||||
|
|
||||||
rules = [self _indexedRules: [self exceptionRules]];
|
|
||||||
if (rules)
|
|
||||||
[cycleInfo setObject: rules forKey: @"exRules"];
|
|
||||||
|
|
||||||
rules = [self _indexedRules: [self exceptionDates]];
|
|
||||||
if (rules)
|
|
||||||
[cycleInfo setObject: rules forKey: @"exDates"];
|
|
||||||
|
|
||||||
value = [cycleInfo description];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
value = nil;
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
2008-07-11 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||||
|
|
||||||
|
* iCalEntityObject.m ([iCalEntityObject -setRecurrenceId:newRecId])
|
||||||
|
([iCalEntityObject -recurrenceId]): new accessors to handle the
|
||||||
|
"RECURRENCE-ID" fields in recurrence exceptions.
|
||||||
|
|
||||||
2008-07-07 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
2008-07-07 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||||
|
|
||||||
* CardElement.m ([CardElement -addValue:aValue])
|
* CardElement.m ([CardElement -addValue:aValue])
|
||||||
|
|
|
@ -190,8 +190,8 @@
|
||||||
- (NSArray *) allObjects
|
- (NSArray *) allObjects
|
||||||
{
|
{
|
||||||
NSMutableArray *ma;
|
NSMutableArray *ma;
|
||||||
|
|
||||||
ma = [NSMutableArray new];
|
ma = [NSMutableArray array];
|
||||||
[ma addObjectsFromArray: [self events]];
|
[ma addObjectsFromArray: [self events]];
|
||||||
[ma addObjectsFromArray: [self todos]];
|
[ma addObjectsFromArray: [self todos]];
|
||||||
[ma addObjectsFromArray: [self journals]];
|
[ma addObjectsFromArray: [self journals]];
|
||||||
|
|
|
@ -79,6 +79,9 @@ typedef enum
|
||||||
- (NSCalendarDate *) startDate;
|
- (NSCalendarDate *) startDate;
|
||||||
- (BOOL) hasStartDate;
|
- (BOOL) hasStartDate;
|
||||||
|
|
||||||
|
- (void) setRecurrenceId: (NSCalendarDate *) newRecId;
|
||||||
|
- (NSCalendarDate *) recurrenceId;
|
||||||
|
|
||||||
- (void) setLastModified: (NSCalendarDate *) _value;
|
- (void) setLastModified: (NSCalendarDate *) _value;
|
||||||
- (NSCalendarDate *) lastModified;
|
- (NSCalendarDate *) lastModified;
|
||||||
|
|
||||||
|
@ -110,7 +113,7 @@ typedef enum
|
||||||
- (NSArray *) resources;
|
- (NSArray *) resources;
|
||||||
- (BOOL) isParticipant: (id) _email;
|
- (BOOL) isParticipant: (id) _email;
|
||||||
- (iCalPerson *) findParticipantWithEmail: (id) _email;
|
- (iCalPerson *) findParticipantWithEmail: (id) _email;
|
||||||
|
|
||||||
- (void) removeAllAlarms;
|
- (void) removeAllAlarms;
|
||||||
- (void) addToAlarms: (id) _alarm;
|
- (void) addToAlarms: (id) _alarm;
|
||||||
- (NSArray *) alarms;
|
- (NSArray *) alarms;
|
||||||
|
|
|
@ -60,6 +60,7 @@
|
||||||
tagClass = [CardElement class];
|
tagClass = [CardElement class];
|
||||||
else if ([classTag isEqualToString: @"DTSTAMP"]
|
else if ([classTag isEqualToString: @"DTSTAMP"]
|
||||||
|| [classTag isEqualToString: @"DTSTART"]
|
|| [classTag isEqualToString: @"DTSTART"]
|
||||||
|
|| [classTag isEqualToString: @"RECURRENCE-ID"]
|
||||||
|| [classTag isEqualToString: @"CREATED"]
|
|| [classTag isEqualToString: @"CREATED"]
|
||||||
|| [classTag isEqualToString: @"LAST-MODIFIED"])
|
|| [classTag isEqualToString: @"LAST-MODIFIED"])
|
||||||
tagClass = [iCalDateTime class];
|
tagClass = [iCalDateTime class];
|
||||||
|
@ -257,6 +258,18 @@
|
||||||
dateTime];
|
dateTime];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) setRecurrenceId: (NSCalendarDate *) newRecId
|
||||||
|
{
|
||||||
|
[(iCalDateTime *) [self uniqueChildWithTag: @"recurrence-id"]
|
||||||
|
setDateTime: newRecId];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSCalendarDate *) recurrenceId
|
||||||
|
{
|
||||||
|
return [(iCalDateTime *) [self uniqueChildWithTag: @"recurrence-id"]
|
||||||
|
dateTime];
|
||||||
|
}
|
||||||
|
|
||||||
- (BOOL) hasStartDate
|
- (BOOL) hasStartDate
|
||||||
{
|
{
|
||||||
return ([[self childrenWithTag: @"dtstart"] count] > 0);
|
return ([[self childrenWithTag: @"dtstart"] count] > 0);
|
||||||
|
|
|
@ -11,9 +11,11 @@ Appointments_OBJC_FILES = \
|
||||||
Product.m \
|
Product.m \
|
||||||
NSArray+Appointments.m \
|
NSArray+Appointments.m \
|
||||||
iCalEntityObject+SOGo.m \
|
iCalEntityObject+SOGo.m \
|
||||||
|
iCalRepeatableEntityObject+SOGo.m \
|
||||||
iCalEvent+SOGo.m \
|
iCalEvent+SOGo.m \
|
||||||
iCalEventChanges+SOGo.m \
|
iCalEventChanges+SOGo.m \
|
||||||
iCalPerson+SOGo.m \
|
iCalPerson+SOGo.m \
|
||||||
|
iCalToDo+SOGo.m \
|
||||||
\
|
\
|
||||||
SOGoCalendarComponent.m \
|
SOGoCalendarComponent.m \
|
||||||
SOGoAppointmentObject.m \
|
SOGoAppointmentObject.m \
|
||||||
|
|
|
@ -59,12 +59,14 @@
|
||||||
#import <SOGo/SOGoCache.h>
|
#import <SOGo/SOGoCache.h>
|
||||||
// #import <SOGo/SOGoCustomGroupFolder.h>
|
// #import <SOGo/SOGoCustomGroupFolder.h>
|
||||||
#import <SOGo/LDAPUserManager.h>
|
#import <SOGo/LDAPUserManager.h>
|
||||||
|
#import <SOGo/NSDictionary+Utilities.h>
|
||||||
#import <SOGo/SOGoPermissions.h>
|
#import <SOGo/SOGoPermissions.h>
|
||||||
#import <SOGo/SOGoUser.h>
|
#import <SOGo/SOGoUser.h>
|
||||||
#import <SOGo/SOGoUserFolder.h>
|
#import <SOGo/SOGoUserFolder.h>
|
||||||
#import <SOGo/SOGoWebDAVAclManager.h>
|
#import <SOGo/SOGoWebDAVAclManager.h>
|
||||||
#import <SoObjects/SOGo/iCalEntityObject+Utilities.h>
|
#import <SOGo/iCalEntityObject+Utilities.h>
|
||||||
|
|
||||||
|
#import "iCalEntityObject+SOGo.h"
|
||||||
#import "SOGoAppointmentObject.h"
|
#import "SOGoAppointmentObject.h"
|
||||||
#import "SOGoAppointmentFolders.h"
|
#import "SOGoAppointmentFolders.h"
|
||||||
#import "SOGoFreeBusyObject.h"
|
#import "SOGoFreeBusyObject.h"
|
||||||
|
@ -98,7 +100,10 @@ static Class sogoAppointmentFolderKlass = Nil;
|
||||||
didInit = YES;
|
didInit = YES;
|
||||||
|
|
||||||
if (!sogoAppointmentFolderKlass)
|
if (!sogoAppointmentFolderKlass)
|
||||||
sogoAppointmentFolderKlass = self;
|
{
|
||||||
|
sogoAppointmentFolderKlass = self;
|
||||||
|
[iCalEntityObject initializeSOGoExtensions];
|
||||||
|
}
|
||||||
|
|
||||||
if (!reportQueryFields)
|
if (!reportQueryFields)
|
||||||
reportQueryFields = [[NSArray alloc] initWithObjects: @"c_name",
|
reportQueryFields = [[NSArray alloc] initWithObjects: @"c_name",
|
||||||
|
@ -554,7 +559,6 @@ static Class sogoAppointmentFolderKlass = Nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSMutableDictionary *) fixupRecord: (NSDictionary *) _record
|
- (NSMutableDictionary *) fixupRecord: (NSDictionary *) _record
|
||||||
fetchRange: (NGCalendarDateRange *) _r
|
|
||||||
{
|
{
|
||||||
NSMutableDictionary *md;
|
NSMutableDictionary *md;
|
||||||
static NSString *fields[] = { @"c_startdate", @"startDate",
|
static NSString *fields[] = { @"c_startdate", @"startDate",
|
||||||
|
@ -598,8 +602,7 @@ static Class sogoAppointmentFolderKlass = Nil;
|
||||||
ma = [NSMutableArray arrayWithCapacity: max];
|
ma = [NSMutableArray arrayWithCapacity: max];
|
||||||
for (count = 0; count < max; count++)
|
for (count = 0; count < max; count++)
|
||||||
{
|
{
|
||||||
row = [self fixupRecord: [records objectAtIndex: count]
|
row = [self fixupRecord: [records objectAtIndex: count]];
|
||||||
fetchRange: r];
|
|
||||||
if (row)
|
if (row)
|
||||||
[ma addObject: row];
|
[ma addObject: row];
|
||||||
}
|
}
|
||||||
|
@ -632,6 +635,117 @@ static Class sogoAppointmentFolderKlass = Nil;
|
||||||
return md;
|
return md;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (int) _indexOfRecordMatchingDate: (NSCalendarDate *) matchDate
|
||||||
|
inArray: (NSArray *) recordArray
|
||||||
|
{
|
||||||
|
int count, max, recordIndex;
|
||||||
|
NSDictionary *currentRecord;
|
||||||
|
|
||||||
|
recordIndex = -1;
|
||||||
|
|
||||||
|
count = 0;
|
||||||
|
max = [recordArray count];
|
||||||
|
while (recordIndex == -1 && count < max)
|
||||||
|
{
|
||||||
|
currentRecord = [recordArray objectAtIndex: count];
|
||||||
|
if ([[currentRecord objectForKey: @"startDate"]
|
||||||
|
isEqual: matchDate])
|
||||||
|
recordIndex = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
return recordIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) _fixExceptionRecord: (NSMutableDictionary *) recRecord
|
||||||
|
fromRow: (NSDictionary *) row
|
||||||
|
{
|
||||||
|
NSArray *objects;
|
||||||
|
static NSArray *fields = nil;
|
||||||
|
|
||||||
|
if (!fields)
|
||||||
|
{
|
||||||
|
fields = [NSArray arrayWithObjects: @"c_name", nil];
|
||||||
|
[fields retain];
|
||||||
|
}
|
||||||
|
|
||||||
|
objects = [row objectsForKeys: fields notFoundMarker: @""];
|
||||||
|
[recRecord setObjects: objects forKeys: fields];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) _appendCycleException: (iCalRepeatableEntityObject *) component
|
||||||
|
fromRow: (NSDictionary *) row
|
||||||
|
forRange: (NGCalendarDateRange *) dateRange
|
||||||
|
toArray: (NSMutableArray *) ma
|
||||||
|
{
|
||||||
|
NSCalendarDate *startDate, *recurrenceId;
|
||||||
|
NSMutableDictionary *newRecord;
|
||||||
|
NGCalendarDateRange *newRecordRange;
|
||||||
|
int recordIndex;
|
||||||
|
|
||||||
|
newRecord = nil;
|
||||||
|
|
||||||
|
recurrenceId = [component recurrenceId];
|
||||||
|
if ([dateRange containsDate: recurrenceId])
|
||||||
|
{
|
||||||
|
recordIndex = [self _indexOfRecordMatchingDate: recurrenceId
|
||||||
|
inArray: ma];
|
||||||
|
if (recordIndex > -1)
|
||||||
|
{
|
||||||
|
startDate = [component startDate];
|
||||||
|
if ([dateRange containsDate: startDate])
|
||||||
|
{
|
||||||
|
newRecord = [self fixupRecord: [component quickRecord]];
|
||||||
|
[ma replaceObjectAtIndex: recordIndex withObject: newRecord];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
[ma removeObjectAtIndex: recordIndex];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
[self errorWithFormat:
|
||||||
|
@"missing exception record for recurrence-id: %@",
|
||||||
|
recurrenceId];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
newRecord = [self fixupRecord: [component quickRecord]];
|
||||||
|
newRecordRange = [NGCalendarDateRange calendarDateRangeWithStartDate:
|
||||||
|
[newRecord objectForKey:
|
||||||
|
@"startDate"]
|
||||||
|
endDate: [newRecord objectForKey:
|
||||||
|
@"endDate"]];
|
||||||
|
if ([dateRange doesIntersectWithDateRange: newRecordRange])
|
||||||
|
[ma addObject: newRecord];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (newRecord)
|
||||||
|
[self _fixExceptionRecord: newRecord fromRow: row];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) _appendCycleExceptionsFromRow: (NSDictionary *) row
|
||||||
|
forRange: (NGCalendarDateRange *) dateRange
|
||||||
|
toArray: (NSMutableArray *) ma
|
||||||
|
{
|
||||||
|
NSArray *elements, *components;
|
||||||
|
unsigned int count, max;
|
||||||
|
NSString *content;
|
||||||
|
|
||||||
|
content = [row objectForKey: @"c_content"];
|
||||||
|
if ([content length])
|
||||||
|
{
|
||||||
|
elements = [iCalCalendar parseFromSource: content];
|
||||||
|
if ([elements count])
|
||||||
|
{
|
||||||
|
components = [[elements objectAtIndex: 0] allObjects];
|
||||||
|
max = [components count];
|
||||||
|
for (count = 1; count < max; count++)
|
||||||
|
[self _appendCycleException: [components objectAtIndex: count]
|
||||||
|
fromRow: row
|
||||||
|
forRange: dateRange
|
||||||
|
toArray: ma];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (void) _flattenCycleRecord: (NSDictionary *) _row
|
- (void) _flattenCycleRecord: (NSDictionary *) _row
|
||||||
forRange: (NGCalendarDateRange *) _r
|
forRange: (NGCalendarDateRange *) _r
|
||||||
intoArray: (NSMutableArray *) _ma
|
intoArray: (NSMutableArray *) _ma
|
||||||
|
@ -660,7 +774,7 @@ static Class sogoAppointmentFolderKlass = Nil;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
row = [self fixupRecord:_row fetchRange: _r];
|
row = [self fixupRecord: _row];
|
||||||
[row removeObjectForKey: @"c_cycleinfo"];
|
[row removeObjectForKey: @"c_cycleinfo"];
|
||||||
[row setObject: sharedYes forKey: @"isRecurrentEvent"];
|
[row setObject: sharedYes forKey: @"isRecurrentEvent"];
|
||||||
|
|
||||||
|
@ -685,6 +799,10 @@ static Class sogoAppointmentFolderKlass = Nil;
|
||||||
if (fixedRow)
|
if (fixedRow)
|
||||||
[_ma addObject:fixedRow];
|
[_ma addObject:fixedRow];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[self _appendCycleExceptionsFromRow: row
|
||||||
|
forRange: _r
|
||||||
|
toArray: _ma];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSArray *) fixupCyclicRecords: (NSArray *) _records
|
- (NSArray *) fixupCyclicRecords: (NSArray *) _records
|
||||||
|
@ -693,16 +811,16 @@ static Class sogoAppointmentFolderKlass = Nil;
|
||||||
// TODO: is the result supposed to be sorted by date?
|
// TODO: is the result supposed to be sorted by date?
|
||||||
NSMutableArray *ma;
|
NSMutableArray *ma;
|
||||||
NSDictionary *row;
|
NSDictionary *row;
|
||||||
unsigned int i, count;
|
unsigned int count, max;
|
||||||
|
|
||||||
count = [_records count];
|
max = [_records count];
|
||||||
ma = [NSMutableArray arrayWithCapacity: count];
|
ma = [NSMutableArray arrayWithCapacity: max];
|
||||||
if (count > 0)
|
|
||||||
for (i = 0; i < count; i++)
|
for (count = 0; count < max; count++)
|
||||||
{
|
{
|
||||||
row = [_records objectAtIndex: i];
|
row = [_records objectAtIndex: count];
|
||||||
[self _flattenCycleRecord: row forRange: _r intoArray: ma];
|
[self _flattenCycleRecord: row forRange: _r intoArray: ma];
|
||||||
}
|
}
|
||||||
|
|
||||||
return ma;
|
return ma;
|
||||||
}
|
}
|
||||||
|
@ -844,9 +962,10 @@ static Class sogoAppointmentFolderKlass = Nil;
|
||||||
{
|
{
|
||||||
if (r)
|
if (r)
|
||||||
records = [self fixupCyclicRecords: records fetchRange: r];
|
records = [self fixupCyclicRecords: records fetchRange: r];
|
||||||
if (!ma)
|
if (ma)
|
||||||
ma = [NSMutableArray arrayWithCapacity: [records count]];
|
[ma addObjectsFromArray: records];
|
||||||
[ma addObjectsFromArray: records];
|
else
|
||||||
|
ma = [NSMutableArray arrayWithArray: records];
|
||||||
}
|
}
|
||||||
else if (!ma)
|
else if (!ma)
|
||||||
{
|
{
|
||||||
|
@ -891,6 +1010,8 @@ static Class sogoAppointmentFolderKlass = Nil;
|
||||||
#warning we should use the EOFetchSpecification for that!!! (see doPROPFIND:)
|
#warning we should use the EOFetchSpecification for that!!! (see doPROPFIND:)
|
||||||
|
|
||||||
#warning components in calendar-data query are ignored
|
#warning components in calendar-data query are ignored
|
||||||
|
|
||||||
|
#warning the two following methods should be replaced with the new dav rendering mechanism
|
||||||
- (NSString *) _nodeTagForProperty: (NSString *) property
|
- (NSString *) _nodeTagForProperty: (NSString *) property
|
||||||
{
|
{
|
||||||
NSString *namespace, *nodeName, *nsRep;
|
NSString *namespace, *nodeName, *nsRep;
|
||||||
|
|
|
@ -27,8 +27,13 @@
|
||||||
|
|
||||||
@class SOGoUser;
|
@class SOGoUser;
|
||||||
|
|
||||||
|
NSCalendarDate *iCalDistantFuture;
|
||||||
|
NSNumber *iCalDistantFutureNumber;
|
||||||
|
|
||||||
@interface iCalEntityObject (SOGoExtensions)
|
@interface iCalEntityObject (SOGoExtensions)
|
||||||
|
|
||||||
|
+ (void) initializeSOGoExtensions;
|
||||||
|
|
||||||
- (BOOL) userIsParticipant: (SOGoUser *) user;
|
- (BOOL) userIsParticipant: (SOGoUser *) user;
|
||||||
- (BOOL) userIsOrganizer: (SOGoUser *) user;
|
- (BOOL) userIsOrganizer: (SOGoUser *) user;
|
||||||
|
|
||||||
|
@ -38,6 +43,10 @@
|
||||||
- (id) itipEntryWithMethod: (NSString *) method;
|
- (id) itipEntryWithMethod: (NSString *) method;
|
||||||
|
|
||||||
- (NSArray *) attendeesWithoutUser: (SOGoUser *) user;
|
- (NSArray *) attendeesWithoutUser: (SOGoUser *) user;
|
||||||
|
- (NSMutableDictionary *) quickRecord;
|
||||||
|
|
||||||
|
- (int) priorityNumber;
|
||||||
|
- (NSNumber *) quickRecordDateAsNumber: (NSCalendarDate *) _date;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#import <Foundation/NSArray.h>
|
#import <Foundation/NSArray.h>
|
||||||
#import <Foundation/NSEnumerator.h>
|
#import <Foundation/NSEnumerator.h>
|
||||||
#import <Foundation/NSString.h>
|
#import <Foundation/NSString.h>
|
||||||
|
#import <Foundation/NSValue.h>
|
||||||
|
|
||||||
#import <NGCards/iCalCalendar.h>
|
#import <NGCards/iCalCalendar.h>
|
||||||
#import <NGCards/iCalPerson.h>
|
#import <NGCards/iCalPerson.h>
|
||||||
|
@ -36,6 +37,16 @@
|
||||||
|
|
||||||
@implementation iCalEntityObject (SOGoExtensions)
|
@implementation iCalEntityObject (SOGoExtensions)
|
||||||
|
|
||||||
|
+ (void) initializeSOGoExtensions;
|
||||||
|
{
|
||||||
|
if (!iCalDistantFuture)
|
||||||
|
{
|
||||||
|
iCalDistantFuture = [[NSCalendarDate distantFuture] retain];
|
||||||
|
/* INT_MAX due to Postgres constraint */
|
||||||
|
iCalDistantFutureNumber = [[NSNumber numberWithUnsignedInt: INT_MAX] retain];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (BOOL) userIsParticipant: (SOGoUser *) user
|
- (BOOL) userIsParticipant: (SOGoUser *) user
|
||||||
{
|
{
|
||||||
NSEnumerator *participants;
|
NSEnumerator *participants;
|
||||||
|
@ -128,4 +139,38 @@
|
||||||
return newAttendees;
|
return newAttendees;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSNumber *) quickRecordDateAsNumber: (NSCalendarDate *) _date
|
||||||
|
{
|
||||||
|
return ((_date == iCalDistantFuture)
|
||||||
|
? iCalDistantFutureNumber
|
||||||
|
: [NSNumber numberWithUnsignedInt: [_date timeIntervalSince1970]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSMutableDictionary *) quickRecord
|
||||||
|
{
|
||||||
|
[self subclassResponsibility: _cmd];
|
||||||
|
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (int) priorityNumber
|
||||||
|
{
|
||||||
|
NSString *prio;
|
||||||
|
NSRange r;
|
||||||
|
int priorityNumber;
|
||||||
|
|
||||||
|
prio = [self priority];
|
||||||
|
if (prio)
|
||||||
|
{
|
||||||
|
r = [prio rangeOfString: @";"];
|
||||||
|
if (r.length)
|
||||||
|
prio = [prio substringToIndex:r.location];
|
||||||
|
priorityNumber = [prio intValue];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
priorityNumber = 0;
|
||||||
|
|
||||||
|
return priorityNumber;
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -25,9 +25,12 @@
|
||||||
|
|
||||||
#import <NGCards/iCalEvent.h>
|
#import <NGCards/iCalEvent.h>
|
||||||
|
|
||||||
|
@class NSMutableDictionary;
|
||||||
|
|
||||||
@interface iCalEvent (SOGoExtensions)
|
@interface iCalEvent (SOGoExtensions)
|
||||||
|
|
||||||
- (BOOL) isStillRelevant;
|
- (BOOL) isStillRelevant;
|
||||||
|
- (NSMutableDictionary *) quickRecord;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,18 @@
|
||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#import <Foundation/NSArray.h>
|
||||||
#import <Foundation/NSCalendarDate.h>
|
#import <Foundation/NSCalendarDate.h>
|
||||||
|
#import <Foundation/NSDictionary.h>
|
||||||
|
#import <Foundation/NSValue.h>
|
||||||
|
|
||||||
|
#import <NGExtensions/NSNull+misc.h>
|
||||||
|
#import <NGExtensions/NSObject+Logs.h>
|
||||||
|
|
||||||
|
#import <NGCards/iCalEvent.h>
|
||||||
|
#import <NGCards/iCalPerson.h>
|
||||||
|
|
||||||
|
#import "iCalRepeatableEntityObject+SOGo.h"
|
||||||
|
|
||||||
#import "iCalEvent+SOGo.h"
|
#import "iCalEvent+SOGo.h"
|
||||||
|
|
||||||
|
@ -35,4 +46,150 @@
|
||||||
return ([[self endDate] earlierDate: now] == now);
|
return ([[self endDate] earlierDate: now] == now);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSMutableDictionary *) quickRecord
|
||||||
|
{
|
||||||
|
NSMutableDictionary *row;
|
||||||
|
NSCalendarDate *startDate, *endDate;
|
||||||
|
NSArray *attendees;
|
||||||
|
NSString *uid, *title, *location, *status;
|
||||||
|
NSNumber *sequence, *dateNumber;
|
||||||
|
id organizer;
|
||||||
|
id participants, partmails;
|
||||||
|
NSMutableString *partstates;
|
||||||
|
unsigned int i, count, boolTmp;
|
||||||
|
BOOL isAllDay;
|
||||||
|
iCalAccessClass accessClass;
|
||||||
|
|
||||||
|
/* extract values */
|
||||||
|
|
||||||
|
startDate = [self startDate];
|
||||||
|
endDate = [self endDate];
|
||||||
|
uid = [self uid];
|
||||||
|
title = [self summary];
|
||||||
|
if (![title isNotNull])
|
||||||
|
title = @"";
|
||||||
|
location = [self location];
|
||||||
|
sequence = [self sequence];
|
||||||
|
accessClass = [self symbolicAccessClass];
|
||||||
|
isAllDay = [self isAllDay];
|
||||||
|
status = [[self status] uppercaseString];
|
||||||
|
|
||||||
|
attendees = [self attendees];
|
||||||
|
partmails = [attendees valueForKey: @"rfc822Email"];
|
||||||
|
partmails = [partmails componentsJoinedByString: @"\n"];
|
||||||
|
participants = [attendees valueForKey: @"cn"];
|
||||||
|
participants = [participants componentsJoinedByString: @"\n"];
|
||||||
|
|
||||||
|
/* build row */
|
||||||
|
|
||||||
|
row = [NSMutableDictionary dictionaryWithCapacity:8];
|
||||||
|
|
||||||
|
[row setObject: @"vevent" forKey: @"c_component"];
|
||||||
|
|
||||||
|
if ([uid isNotNull])
|
||||||
|
[row setObject:uid forKey: @"c_uid"];
|
||||||
|
else
|
||||||
|
[self logWithFormat: @"WARNING: could not extract a uid from event!"];
|
||||||
|
|
||||||
|
boolTmp = ((isAllDay) ? 1 : 0);
|
||||||
|
[row setObject: [NSNumber numberWithInt: boolTmp]
|
||||||
|
forKey: @"c_isallday"];
|
||||||
|
boolTmp = (([self isRecurrent]) ? 1 : 0);
|
||||||
|
[row setObject: [NSNumber numberWithInt: boolTmp]
|
||||||
|
forKey: @"c_iscycle"];
|
||||||
|
boolTmp = (([self isOpaque]) ? 1 : 0);
|
||||||
|
[row setObject: [NSNumber numberWithInt: boolTmp]
|
||||||
|
forKey: @"c_isopaque"];
|
||||||
|
[row setObject: [NSNumber numberWithInt: [self priorityNumber]]
|
||||||
|
forKey: @"c_priority"];
|
||||||
|
|
||||||
|
[row setObject: title forKey: @"c_title"];
|
||||||
|
if ([location isNotNull]) [row setObject: location forKey: @"c_location"];
|
||||||
|
if ([sequence isNotNull]) [row setObject: sequence forKey: @"c_sequence"];
|
||||||
|
|
||||||
|
if ([startDate isNotNull])
|
||||||
|
[row setObject: [self quickRecordDateAsNumber: startDate]
|
||||||
|
forKey: @"c_startdate"];
|
||||||
|
if ([endDate isNotNull])
|
||||||
|
{
|
||||||
|
if (endDate == iCalDistantFuture)
|
||||||
|
dateNumber = iCalDistantFutureNumber;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (isAllDay)
|
||||||
|
i = 1;
|
||||||
|
else
|
||||||
|
i = 0;
|
||||||
|
dateNumber
|
||||||
|
= [NSNumber numberWithUnsignedInt:
|
||||||
|
[endDate timeIntervalSince1970] - i];
|
||||||
|
}
|
||||||
|
[row setObject: dateNumber forKey: @"c_enddate"];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ([self isRecurrent]) {
|
||||||
|
NSCalendarDate *date;
|
||||||
|
|
||||||
|
date = [self lastPossibleRecurrenceStartDate];
|
||||||
|
if (!date) {
|
||||||
|
/* this could also be *nil*, but in the end it makes the fetchspecs
|
||||||
|
more complex - thus we set it to a "reasonable" distant future */
|
||||||
|
date = iCalDistantFuture;
|
||||||
|
}
|
||||||
|
[row setObject:[self quickRecordDateAsNumber:date] forKey: @"c_cycleenddate"];
|
||||||
|
[row setObject:[self cycleInfo] forKey: @"c_cycleinfo"];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ([participants length] > 0)
|
||||||
|
[row setObject: participants forKey: @"c_participants"];
|
||||||
|
if ([partmails length] > 0)
|
||||||
|
[row setObject: partmails forKey: @"c_partmails"];
|
||||||
|
|
||||||
|
if ([status isNotNull]) {
|
||||||
|
int code = 1;
|
||||||
|
|
||||||
|
if ([status isEqualToString: @"TENTATIVE"])
|
||||||
|
code = 2;
|
||||||
|
else if ([status isEqualToString: @"CANCELLED"])
|
||||||
|
code = 0;
|
||||||
|
[row setObject:[NSNumber numberWithInt:code] forKey: @"c_status"];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* confirmed by default */
|
||||||
|
[row setObject: [NSNumber numberWithInt:1] forKey: @"c_status"];
|
||||||
|
}
|
||||||
|
|
||||||
|
[row setObject: [NSNumber numberWithUnsignedInt: accessClass]
|
||||||
|
forKey: @"c_classification"];
|
||||||
|
|
||||||
|
organizer = [self organizer];
|
||||||
|
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];
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
iCalPerson *p;
|
||||||
|
iCalPersonPartStat stat;
|
||||||
|
|
||||||
|
p = [attendees objectAtIndex:i];
|
||||||
|
stat = [p participationStatus];
|
||||||
|
if (i)
|
||||||
|
[partstates appendString: @"\n"];
|
||||||
|
[partstates appendFormat: @"%d", stat];
|
||||||
|
}
|
||||||
|
[row setObject:partstates forKey: @"c_partstates"];
|
||||||
|
[partstates release];
|
||||||
|
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
/* iCalRepeatableEntityObject+SOGo.h - this file is part of SOGo
|
||||||
|
Copyright (C) 2004-2005 SKYRIX Software AG
|
||||||
|
Copyright (C) 2008 Inverse groupe conseil
|
||||||
|
|
||||||
|
This file is part of OpenGroupware.org.
|
||||||
|
|
||||||
|
OGo is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU Lesser General Public License as published by the
|
||||||
|
Free Software Foundation; either version 2, or (at your option) any
|
||||||
|
later version.
|
||||||
|
|
||||||
|
OGo is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||||
|
License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with OGo; see the file COPYING. If not, write to the
|
||||||
|
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import <NGCards/iCalRepeatableEntityObject.h>
|
||||||
|
|
||||||
|
#import "iCalEntityObject+SOGo.h"
|
||||||
|
|
||||||
|
@class NSString;
|
||||||
|
|
||||||
|
@interface iCalRepeatableEntityObject (SOGoExtensions)
|
||||||
|
|
||||||
|
- (NSString *) cycleInfo;
|
||||||
|
|
||||||
|
@end
|
|
@ -0,0 +1,89 @@
|
||||||
|
/* iCalRepeatableEntityObject+SOGo.m - this file is part of SOGo
|
||||||
|
Copyright (C) 2004-2005 SKYRIX Software AG
|
||||||
|
Copyright (C) 2008 Inverse groupe conseil
|
||||||
|
|
||||||
|
This file is part of OpenGroupware.org.
|
||||||
|
|
||||||
|
OGo is free software; you can redistribute it and/or modify it under
|
||||||
|
the terms of the GNU Lesser General Public License as published by the
|
||||||
|
Free Software Foundation; either version 2, or (at your option) any
|
||||||
|
later version.
|
||||||
|
|
||||||
|
OGo is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||||
|
License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with OGo; see the file COPYING. If not, write to the
|
||||||
|
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import <Foundation/NSArray.h>
|
||||||
|
#import <Foundation/NSDictionary.h>
|
||||||
|
#import <Foundation/NSString.h>
|
||||||
|
|
||||||
|
#import <NGCards/iCalRecurrenceRule.h>
|
||||||
|
|
||||||
|
#import "iCalRepeatableEntityObject+SOGo.h"
|
||||||
|
|
||||||
|
@implementation iCalRepeatableEntityObject (SOGoExtensions)
|
||||||
|
|
||||||
|
- (NSArray *) _indexedRules: (NSArray *) rules
|
||||||
|
{
|
||||||
|
NSMutableArray *ma;
|
||||||
|
unsigned int i, count;
|
||||||
|
NSString *valuesString;
|
||||||
|
|
||||||
|
ma = nil;
|
||||||
|
count = [rules count];
|
||||||
|
if (count > 0)
|
||||||
|
{
|
||||||
|
ma = [NSMutableArray arrayWithCapacity:count];
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
iCalRecurrenceRule *rule;
|
||||||
|
|
||||||
|
rule = [rules objectAtIndex:i];
|
||||||
|
#warning we could return an NSArray instead and feed it as such to the iCalRecurrenceRule in SOGoAppointmentFolder...
|
||||||
|
valuesString = [[rule values] componentsJoinedByString: @";"];
|
||||||
|
[ma addObject: valuesString];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ma;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *) cycleInfo
|
||||||
|
{
|
||||||
|
NSArray *rules;
|
||||||
|
NSString *value;
|
||||||
|
NSMutableDictionary *cycleInfo;
|
||||||
|
|
||||||
|
if ([self isRecurrent])
|
||||||
|
{
|
||||||
|
cycleInfo = [NSMutableDictionary dictionaryWithCapacity: 3];
|
||||||
|
|
||||||
|
/* rules */
|
||||||
|
rules = [self _indexedRules: [self recurrenceRules]];
|
||||||
|
if (rules)
|
||||||
|
[cycleInfo setObject: rules forKey: @"rules"];
|
||||||
|
|
||||||
|
rules = [self _indexedRules: [self exceptionRules]];
|
||||||
|
if (rules)
|
||||||
|
[cycleInfo setObject: rules forKey: @"exRules"];
|
||||||
|
|
||||||
|
rules = [self _indexedRules: [self exceptionDates]];
|
||||||
|
if (rules)
|
||||||
|
[cycleInfo setObject: rules forKey: @"exDates"];
|
||||||
|
|
||||||
|
value = [cycleInfo description];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
value = nil;
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
|
@ -0,0 +1,36 @@
|
||||||
|
/* iCalToDo+SOGo.h - this file is part of SOGo
|
||||||
|
*
|
||||||
|
* Copyright (C) 2007 Inverse groupe conseil
|
||||||
|
*
|
||||||
|
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
* the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This file is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ICALTODO_SOGO_H
|
||||||
|
#define ICALTODO_SOGO_H
|
||||||
|
|
||||||
|
#import <NGCards/iCalToDo.h>
|
||||||
|
|
||||||
|
@class NSMutableArray;
|
||||||
|
|
||||||
|
@interface iCalToDo (SOGoExtensions)
|
||||||
|
|
||||||
|
- (NSMutableDictionary *) quickRecord;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
#endif /* ICALTODO_SOGO_H */
|
|
@ -0,0 +1,168 @@
|
||||||
|
/* iCalEvent+SOGo.m - this file is part of SOGo
|
||||||
|
*
|
||||||
|
* Copyright (C) 2008 Inverse groupe conseil
|
||||||
|
* Copyright (C) 2004-2005 SKYRIX Software AG
|
||||||
|
*
|
||||||
|
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
* the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This file is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import <Foundation/NSArray.h>
|
||||||
|
#import <Foundation/NSCalendarDate.h>
|
||||||
|
#import <Foundation/NSDictionary.h>
|
||||||
|
#import <Foundation/NSValue.h>
|
||||||
|
|
||||||
|
#import <NGExtensions/NSNull+misc.h>
|
||||||
|
#import <NGExtensions/NSObject+Logs.h>
|
||||||
|
|
||||||
|
#import <NGCards/iCalPerson.h>
|
||||||
|
|
||||||
|
#import "iCalRepeatableEntityObject+SOGo.h"
|
||||||
|
|
||||||
|
#import "iCalToDo+SOGo.h"
|
||||||
|
|
||||||
|
@implementation iCalToDo (SOGoExtensions)
|
||||||
|
|
||||||
|
- (NSMutableDictionary *) quickRecord
|
||||||
|
{
|
||||||
|
NSMutableDictionary *row;
|
||||||
|
NSCalendarDate *startDate, *dueDate;
|
||||||
|
NSArray *attendees;
|
||||||
|
NSString *uid, *title, *location, *status;
|
||||||
|
NSNumber *sequence;
|
||||||
|
id organizer, date;
|
||||||
|
id participants, partmails;
|
||||||
|
NSMutableString *partstates;
|
||||||
|
unsigned i, count, code;
|
||||||
|
iCalAccessClass accessClass;
|
||||||
|
|
||||||
|
/* extract values */
|
||||||
|
|
||||||
|
startDate = [self startDate];
|
||||||
|
dueDate = [self due];
|
||||||
|
uid = [self uid];
|
||||||
|
title = [self summary];
|
||||||
|
if (![title isNotNull])
|
||||||
|
title = @"";
|
||||||
|
location = [self location];
|
||||||
|
sequence = [self sequence];
|
||||||
|
accessClass = [self symbolicAccessClass];
|
||||||
|
status = [[self status] uppercaseString];
|
||||||
|
|
||||||
|
attendees = [self attendees];
|
||||||
|
partmails = [attendees valueForKey: @"rfc822Email"];
|
||||||
|
partmails = [partmails componentsJoinedByString: @"\n"];
|
||||||
|
participants = [attendees valueForKey: @"cn"];
|
||||||
|
participants = [participants componentsJoinedByString: @"\n"];
|
||||||
|
|
||||||
|
/* build row */
|
||||||
|
|
||||||
|
row = [NSMutableDictionary dictionaryWithCapacity:8];
|
||||||
|
|
||||||
|
[row setObject: @"vtodo" forKey: @"c_component"];
|
||||||
|
|
||||||
|
if ([uid isNotNull])
|
||||||
|
[row setObject:uid forKey: @"c_uid"];
|
||||||
|
else
|
||||||
|
[self logWithFormat: @"WARNING: could not extract a uid from event!"];
|
||||||
|
|
||||||
|
[row setObject:[NSNumber numberWithBool:[self isRecurrent]]
|
||||||
|
forKey: @"c_iscycle"];
|
||||||
|
[row setObject:[NSNumber numberWithInt:[self priorityNumber]]
|
||||||
|
forKey: @"c_priority"];
|
||||||
|
|
||||||
|
[row setObject: [NSNumber numberWithBool: NO]
|
||||||
|
forKey: @"c_isallday"];
|
||||||
|
[row setObject: [NSNumber numberWithBool: NO]
|
||||||
|
forKey: @"c_isopaque"];
|
||||||
|
|
||||||
|
[row setObject: title forKey: @"c_title"];
|
||||||
|
if ([location isNotNull]) [row setObject: location forKey: @"c_location"];
|
||||||
|
if ([sequence isNotNull]) [row setObject: sequence forKey: @"c_sequence"];
|
||||||
|
|
||||||
|
if ([startDate isNotNull])
|
||||||
|
date = [self quickRecordDateAsNumber: startDate];
|
||||||
|
else
|
||||||
|
date = [NSNull null];
|
||||||
|
[row setObject: date forKey: @"c_startdate"];
|
||||||
|
|
||||||
|
if ([dueDate isNotNull])
|
||||||
|
date = [self quickRecordDateAsNumber: dueDate];
|
||||||
|
else
|
||||||
|
date = [NSNull null];
|
||||||
|
[row setObject: date forKey: @"c_enddate"];
|
||||||
|
|
||||||
|
if ([self isRecurrent])
|
||||||
|
{
|
||||||
|
[row setObject: [self quickRecordDateAsNumber: iCalDistantFuture]
|
||||||
|
forKey: @"c_cycleenddate"];
|
||||||
|
[row setObject: [self cycleInfo]
|
||||||
|
forKey: @"c_cycleinfo"];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ([participants length] > 0)
|
||||||
|
[row setObject:participants forKey: @"c_participants"];
|
||||||
|
if ([partmails length] > 0)
|
||||||
|
[row setObject:partmails forKey: @"c_partmails"];
|
||||||
|
|
||||||
|
if ([status isNotNull]) {
|
||||||
|
code = 0; /* NEEDS-ACTION */
|
||||||
|
if ([status isEqualToString: @"COMPLETED"])
|
||||||
|
code = 1;
|
||||||
|
else if ([status isEqualToString: @"IN-PROCESS"])
|
||||||
|
code = 2;
|
||||||
|
else if ([status isEqualToString: @"CANCELLED"])
|
||||||
|
code = 3;
|
||||||
|
[row setObject: [NSNumber numberWithInt: code] forKey: @"c_status"];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* confirmed by default */
|
||||||
|
[row setObject:[NSNumber numberWithInt:1] forKey: @"c_status"];
|
||||||
|
}
|
||||||
|
|
||||||
|
[row setObject: [NSNumber numberWithUnsignedInt: accessClass]
|
||||||
|
forKey: @"c_classification"];
|
||||||
|
|
||||||
|
organizer = [self organizer];
|
||||||
|
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];
|
||||||
|
for ( i = 0; i < count; i++) {
|
||||||
|
iCalPerson *p;
|
||||||
|
iCalPersonPartStat stat;
|
||||||
|
|
||||||
|
p = [attendees objectAtIndex:i];
|
||||||
|
stat = [p participationStatus];
|
||||||
|
if(i != 0)
|
||||||
|
[partstates appendString: @"\n"];
|
||||||
|
[partstates appendFormat: @"%d", stat];
|
||||||
|
}
|
||||||
|
[row setObject:partstates forKey: @"c_partstates"];
|
||||||
|
[partstates release];
|
||||||
|
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
#import <Foundation/NSDictionary.h>
|
#import <Foundation/NSDictionary.h>
|
||||||
|
|
||||||
|
@class NSArray;
|
||||||
@class NSString;
|
@class NSString;
|
||||||
|
|
||||||
@interface NSDictionary (SOGoDictionaryUtilities)
|
@interface NSDictionary (SOGoDictionaryUtilities)
|
||||||
|
@ -36,4 +37,11 @@
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@interface NSMutableDictionary (SOGoDictionaryUtilities)
|
||||||
|
|
||||||
|
- (void) setObjects: (NSArray *) objects
|
||||||
|
forKeys: (NSArray *) keys;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
#endif /* NSDICTIONARY_UTILITIES_H */
|
#endif /* NSDICTIONARY_UTILITIES_H */
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#import <Foundation/NSArray.h>
|
#import <Foundation/NSArray.h>
|
||||||
#import <Foundation/NSData.h>
|
#import <Foundation/NSData.h>
|
||||||
#import <Foundation/NSEnumerator.h>
|
#import <Foundation/NSEnumerator.h>
|
||||||
|
#import <Foundation/NSException.h>
|
||||||
#import <Foundation/NSNull.h>
|
#import <Foundation/NSNull.h>
|
||||||
#import <Foundation/NSString.h>
|
#import <Foundation/NSString.h>
|
||||||
|
|
||||||
|
@ -103,3 +104,23 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@implementation NSMutableDictionary (SOGoDictionaryUtilities)
|
||||||
|
|
||||||
|
- (void) setObjects: (NSArray *) objects
|
||||||
|
forKeys: (NSArray *) keys
|
||||||
|
{
|
||||||
|
unsigned int count, max;
|
||||||
|
|
||||||
|
max = [objects count];
|
||||||
|
if ([keys count] == max)
|
||||||
|
for (count = 0; count < max; count++)
|
||||||
|
[self setObject: [objects objectAtIndex: count]
|
||||||
|
forKey: [keys objectAtIndex: count]];
|
||||||
|
else
|
||||||
|
[NSException raise: NSInvalidArgumentException
|
||||||
|
format: @"Number of objects does not match"
|
||||||
|
@" the number of keys."];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
Loading…
Reference in New Issue