Monotone-Parent: 467dc56666485b20c968357bff135be6a192df0c
Monotone-Revision: 81ebf97febc5675193974e8834acc35e001494f1 Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2007-03-18T15:20:38 Monotone-Branch: ca.inverse.sogomaint-2.0.2
parent
84bba82435
commit
d26f7a625a
|
@ -1,5 +1,14 @@
|
||||||
2007-03-18 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
2007-03-18 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||||
|
|
||||||
|
* UI/Scheduler/UIxComponentEditor.m: no longer a superclass for
|
||||||
|
the task and appointment editors. Now a container component
|
||||||
|
handling the common elements of tasks and events.
|
||||||
|
|
||||||
|
* UI/Scheduler/UIxTaskEditor.m: same as below.
|
||||||
|
|
||||||
|
* UI/Scheduler/UIxAppointmentEditor.m: rewrote template. No longer
|
||||||
|
a subclass of UIxComponentEditor but a subcomponent of it.
|
||||||
|
|
||||||
* UI/Common/UIxToolbar.m ([UIxToolbar -toolbarConfig]): the
|
* UI/Common/UIxToolbar.m ([UIxToolbar -toolbarConfig]): the
|
||||||
toolbar can have the special value "none" to indicate there is
|
toolbar can have the special value "none" to indicate there is
|
||||||
none attached to the window.
|
none attached to the window.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* UIxAppointmentEditor.h - this file is part of SOGo
|
/* UIxAppointmentEditor.h - this file is part of SOGo
|
||||||
*
|
*
|
||||||
* Copyright (C) 2006 Inverse groupe conseil
|
* Copyright (C) 2007 Inverse groupe conseil
|
||||||
*
|
*
|
||||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||||
*
|
*
|
||||||
|
@ -23,50 +23,38 @@
|
||||||
#ifndef UIXAPPOINTMENTEDITOR_H
|
#ifndef UIXAPPOINTMENTEDITOR_H
|
||||||
#define UIXAPPOINTMENTEDITOR_H
|
#define UIXAPPOINTMENTEDITOR_H
|
||||||
|
|
||||||
#import <UIxComponentEditor.h>
|
#import <SOGoUI/UIxComponent.h>
|
||||||
|
|
||||||
|
@class iCalEvent;
|
||||||
@class NSString;
|
@class NSString;
|
||||||
@class iCalPerson;
|
|
||||||
@class iCalRecurrenceRule;
|
|
||||||
|
|
||||||
@interface UIxAppointmentEditor : UIxComponentEditor
|
@interface UIxAppointmentEditor : UIxComponent
|
||||||
{
|
{
|
||||||
NSCalendarDate *endDate;
|
iCalEvent *event;
|
||||||
|
NSCalendarDate *aptStartDate;
|
||||||
|
NSCalendarDate *aptEndDate;
|
||||||
|
NSString *item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* template values */
|
||||||
|
- (NSString *) saveURL;
|
||||||
|
- (iCalEvent *) event;
|
||||||
|
|
||||||
|
/* icalendar values */
|
||||||
|
- (BOOL) isAllDay;
|
||||||
|
- (void) setIsAllDay: (BOOL) newIsAllDay;
|
||||||
|
|
||||||
- (void) setAptStartDate: (NSCalendarDate *) _date;
|
- (void) setAptStartDate: (NSCalendarDate *) _date;
|
||||||
- (NSCalendarDate *) aptStartDate;
|
- (NSCalendarDate *) aptStartDate;
|
||||||
|
|
||||||
- (void) setAptEndDate: (NSCalendarDate *) _date;
|
- (void) setAptEndDate: (NSCalendarDate *) _date;
|
||||||
- (NSCalendarDate *) aptEndDate;
|
- (NSCalendarDate *) aptEndDate;
|
||||||
|
|
||||||
/* iCal */
|
- (NSString *) repeat;
|
||||||
|
- (void) setRepeat: (NSString *) newRepeat;
|
||||||
|
|
||||||
- (NSString *) iCalStringTemplate;
|
- (NSString *) reminder;
|
||||||
|
- (void) setReminder: (NSString *) newReminder;
|
||||||
/* new */
|
|
||||||
|
|
||||||
- (id) newAction;
|
|
||||||
|
|
||||||
/* save */
|
|
||||||
|
|
||||||
- (void) loadValuesFromAppointment: (iCalEvent *) _apt;
|
|
||||||
- (void) saveValuesIntoAppointment: (iCalEvent *) _apt;
|
|
||||||
- (iCalEvent *) appointmentFromString: (NSString *) _iCalString;
|
|
||||||
|
|
||||||
/* conflict management */
|
|
||||||
|
|
||||||
- (BOOL) containsConflict: (id) _apt;
|
|
||||||
- (id <WOActionResults>) defaultAction;
|
|
||||||
- (id <WOActionResults>) saveAction;
|
|
||||||
- (id) acceptAction;
|
|
||||||
- (id) declineAction;
|
|
||||||
|
|
||||||
- (NSString *) saveUrl;
|
|
||||||
|
|
||||||
// TODO: add tentatively
|
|
||||||
|
|
||||||
- (id) acceptOrDeclineAction: (BOOL) _accept;
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
|
@ -1,458 +1,366 @@
|
||||||
/*
|
/* UIxAppointmentEditor.m - this file is part of SOGo
|
||||||
Copyright (C) 2004-2005 SKYRIX Software AG
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
This file is part of OpenGroupware.org.
|
#import <NGObjWeb/SoObject.h>
|
||||||
|
#import <NGObjWeb/WORequest.h>
|
||||||
|
#import <NGObjWeb/NSException+HTTP.h>
|
||||||
|
#import <NGExtensions/NSCalendarDate+misc.h>
|
||||||
|
|
||||||
OGo is free software; you can redistribute it and/or modify it under
|
#import <NGCards/iCalEvent.h>
|
||||||
the terms of the GNU Lesser General Public License as published by the
|
#import <NGCards/iCalPerson.h>
|
||||||
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
|
#import <SoObjects/SOGo/AgenorUserManager.h>
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
#import <SoObjects/SOGo/SOGoUser.h>
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
#import <SoObjects/SOGo/SOGoContentObject.h>
|
||||||
License for more details.
|
#import <SoObjects/Appointments/SOGoAppointmentFolder.h>
|
||||||
|
#import <SoObjects/Appointments/SOGoAppointmentObject.h>
|
||||||
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/NSString+NGCards.h>
|
|
||||||
#import <NGCards/NSCalendarDate+NGCards.h>
|
|
||||||
|
|
||||||
#import <SOGo/AgenorUserManager.h>
|
|
||||||
#import <SOGo/NSCalendarDate+SOGo.h>
|
|
||||||
|
|
||||||
#import "common.h"
|
|
||||||
#import <NGCards/NGCards.h>
|
|
||||||
#import <NGExtensions/NGCalendarDateRange.h>
|
|
||||||
#import <SOGoUI/SOGoDateFormatter.h>
|
|
||||||
#import <Appointments/SOGoAppointmentFolder.h>
|
|
||||||
#import <Appointments/SOGoAppointmentObject.h>
|
|
||||||
#import "UIxComponent+Agenor.h"
|
|
||||||
|
|
||||||
|
#import "UIxComponentEditor.h"
|
||||||
#import "UIxAppointmentEditor.h"
|
#import "UIxAppointmentEditor.h"
|
||||||
|
|
||||||
/* TODO: CLEAN UP */
|
|
||||||
|
|
||||||
@implementation UIxAppointmentEditor
|
@implementation UIxAppointmentEditor
|
||||||
|
|
||||||
+ (int)version {
|
- (id) init
|
||||||
return [super version] + 0 /* v2 */;
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (void)initialize {
|
|
||||||
NSAssert2([super version] == 2,
|
|
||||||
@"invalid superclass (%@) version %i !",
|
|
||||||
NSStringFromClass([self superclass]), [super version]);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void) dealloc
|
|
||||||
{
|
{
|
||||||
[endDate release];
|
if ((self = [super init]))
|
||||||
[super dealloc];
|
{
|
||||||
}
|
aptStartDate = nil;
|
||||||
|
aptEndDate = nil;
|
||||||
/* accessors */
|
item = nil;
|
||||||
|
event = nil;
|
||||||
- (void) setAptStartDate: (NSCalendarDate *)_date
|
|
||||||
{
|
|
||||||
[self setStartDate: _date];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSCalendarDate *) aptStartDate
|
|
||||||
{
|
|
||||||
return [self startDate];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void) setAptEndDate: (NSCalendarDate *) _date
|
|
||||||
{
|
|
||||||
ASSIGN(endDate, _date);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSCalendarDate *) aptEndDate
|
|
||||||
{
|
|
||||||
return endDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* transparency */
|
|
||||||
|
|
||||||
- (NSString *) transparency
|
|
||||||
{
|
|
||||||
return @"OPAQUE";
|
|
||||||
}
|
|
||||||
|
|
||||||
/* iCal */
|
|
||||||
|
|
||||||
- (NSString *)iCalStringTemplate {
|
|
||||||
static NSString *iCalStringTemplate = \
|
|
||||||
@"BEGIN:VCALENDAR\r\n"
|
|
||||||
@"METHOD:REQUEST\r\n"
|
|
||||||
@"PRODID://Inverse groupe conseil/SOGo 0.9\r\n"
|
|
||||||
@"VERSION:2.0\r\n"
|
|
||||||
@"BEGIN:VEVENT\r\n"
|
|
||||||
@"UID:%@\r\n"
|
|
||||||
@"CLASS:PUBLIC\r\n"
|
|
||||||
@"STATUS:CONFIRMED\r\n" /* confirmed by default */
|
|
||||||
@"DTSTAMP:%@Z\r\n"
|
|
||||||
@"DTSTART:%@Z\r\n"
|
|
||||||
@"DTEND:%@Z\r\n"
|
|
||||||
@"TRANSP:%@\r\n"
|
|
||||||
@"SEQUENCE:1\r\n"
|
|
||||||
@"PRIORITY:5\r\n"
|
|
||||||
@"%@" /* organizer */
|
|
||||||
@"%@" /* participants and resources */
|
|
||||||
@"END:VEVENT\r\n"
|
|
||||||
@"END:VCALENDAR";
|
|
||||||
|
|
||||||
NSTimeZone *utc;
|
|
||||||
NSCalendarDate *lStartDate, *lEndDate, *stamp;
|
|
||||||
NSString *template, *s;
|
|
||||||
unsigned minutes;
|
|
||||||
|
|
||||||
s = [self queryParameterForKey:@"dur"];
|
|
||||||
if ([s length] > 0)
|
|
||||||
minutes = [s intValue];
|
|
||||||
else
|
|
||||||
minutes = 60;
|
|
||||||
|
|
||||||
utc = [NSTimeZone timeZoneWithName: @"GMT"];
|
|
||||||
lStartDate = [self newStartDate];
|
|
||||||
[lStartDate setTimeZone: utc];
|
|
||||||
lEndDate = [lStartDate dateByAddingYears: 0 months: 0 days: 0
|
|
||||||
hours: 0 minutes: minutes seconds: 0];
|
|
||||||
|
|
||||||
stamp = [NSCalendarDate calendarDate];
|
|
||||||
[stamp setTimeZone: utc];
|
|
||||||
|
|
||||||
s = [self iCalParticipantsAndResourcesStringFromQueryParameters];
|
|
||||||
template = [NSString stringWithFormat: iCalStringTemplate,
|
|
||||||
[[self clientObject] nameInContainer],
|
|
||||||
[stamp iCalFormattedDateTimeString],
|
|
||||||
[lStartDate iCalFormattedDateTimeString],
|
|
||||||
[lEndDate iCalFormattedDateTimeString],
|
|
||||||
[self transparency],
|
|
||||||
[self iCalOrganizerString],
|
|
||||||
s];
|
|
||||||
return template;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* new */
|
|
||||||
|
|
||||||
- (id) newAction
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
This method creates a unique ID and redirects to the "edit" method on the
|
|
||||||
new ID.
|
|
||||||
It is actually a folder method and should be defined on the folder.
|
|
||||||
|
|
||||||
Note: 'clientObject' is the SOGoAppointmentFolder!
|
|
||||||
Update: remember that there are group folders as well.
|
|
||||||
*/
|
|
||||||
NSString *uri, *objectId, *method, *ps;
|
|
||||||
|
|
||||||
objectId = [NSClassFromString(@"SOGoAppointmentFolder")
|
|
||||||
globallyUniqueObjectId];
|
|
||||||
if ([objectId length] == 0) {
|
|
||||||
return [NSException exceptionWithHTTPStatus:500 /* Internal Error */
|
|
||||||
reason:@"could not create a unique ID"];
|
|
||||||
}
|
|
||||||
|
|
||||||
method = [NSString stringWithFormat:@"Calendar/%@/editAsAppointment", objectId];
|
|
||||||
method = [[self userFolderPath] stringByAppendingPathComponent:method];
|
|
||||||
|
|
||||||
/* check if participants have already been provided */
|
|
||||||
ps = [self queryParameterForKey:@"ps"];
|
|
||||||
// if (ps) {
|
|
||||||
// [self setQueryParameter:ps forKey:@"ps"];
|
|
||||||
// }
|
|
||||||
if (!ps
|
|
||||||
&& [[self clientObject] respondsToSelector:@selector(calendarUIDs)]) {
|
|
||||||
AgenorUserManager *um;
|
|
||||||
NSArray *uids;
|
|
||||||
NSMutableArray *emails;
|
|
||||||
unsigned i, count;
|
|
||||||
|
|
||||||
/* add all current calendarUIDs as default participants */
|
|
||||||
|
|
||||||
um = [AgenorUserManager sharedUserManager];
|
|
||||||
uids = [[self clientObject] calendarUIDs];
|
|
||||||
count = [uids count];
|
|
||||||
emails = [NSMutableArray arrayWithCapacity:count];
|
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
|
||||||
NSString *email;
|
|
||||||
|
|
||||||
email = [um getEmailForUID:[uids objectAtIndex:i]];
|
|
||||||
if (email)
|
|
||||||
[emails addObject:email];
|
|
||||||
}
|
}
|
||||||
ps = [emails componentsJoinedByString:@","];
|
|
||||||
[self setQueryParameter:ps forKey:@"ps"];
|
|
||||||
}
|
|
||||||
uri = [self completeHrefForMethod:method];
|
|
||||||
return [self redirectToLocation:uri];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* save */
|
|
||||||
|
|
||||||
- (void) loadValuesFromAppointment: (iCalEvent *) appointment
|
|
||||||
{
|
|
||||||
NSTimeZone *uTZ;
|
|
||||||
|
|
||||||
[self loadValuesFromComponent: appointment];
|
|
||||||
|
|
||||||
uTZ = [[self clientObject] userTimeZone];
|
|
||||||
endDate = [appointment endDate];
|
|
||||||
if (!endDate)
|
|
||||||
endDate = [[self startDate] dateByAddingYears: 0 months: 0 days: 0
|
|
||||||
hours: 1 minutes: 0 seconds: 0];
|
|
||||||
|
|
||||||
[endDate setTimeZone: uTZ];
|
|
||||||
[endDate retain];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void) saveValuesIntoAppointment: (iCalEvent *) _appointment
|
|
||||||
{
|
|
||||||
/* merge in form values */
|
|
||||||
NSArray *attendees, *lResources;
|
|
||||||
iCalRecurrenceRule *rrule;
|
|
||||||
|
|
||||||
[_appointment setStartDate:[self aptStartDate]];
|
|
||||||
[_appointment setEndDate:[self aptEndDate]];
|
|
||||||
|
|
||||||
[_appointment setSummary: [self title]];
|
|
||||||
[_appointment setUrl: [self url]];
|
|
||||||
[_appointment setLocation: [self location]];
|
|
||||||
[_appointment setComment: [self comment]];
|
|
||||||
[_appointment setPriority:[self priority]];
|
|
||||||
[_appointment setAccessClass: [self privacy]];
|
|
||||||
[_appointment setStatus: [self status]];
|
|
||||||
|
|
||||||
// [_appointment setCategories: [[self categories] componentsJoinedByString: @","]];
|
|
||||||
|
|
||||||
[_appointment setTransparency: [self transparency]];
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
/*
|
|
||||||
Note: bad, bad, bad!
|
|
||||||
Organizer is no form value, thus we MUST NOT change it
|
|
||||||
*/
|
|
||||||
[_appointment setOrganizer:organizer];
|
|
||||||
#endif
|
|
||||||
attendees = [self participants];
|
|
||||||
lResources = [self resources];
|
|
||||||
if ([lResources count] > 0) {
|
|
||||||
attendees = ([attendees count] > 0)
|
|
||||||
? [attendees arrayByAddingObjectsFromArray: lResources]
|
|
||||||
: lResources;
|
|
||||||
}
|
|
||||||
[attendees makeObjectsPerformSelector: @selector (setTag:)
|
|
||||||
withObject: @"attendee"];
|
|
||||||
[_appointment setAttendees: attendees];
|
|
||||||
|
|
||||||
/* cycles */
|
|
||||||
[_appointment removeAllRecurrenceRules];
|
|
||||||
rrule = [self rrule];
|
|
||||||
if (rrule)
|
|
||||||
[_appointment addToRecurrenceRules: rrule];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (iCalEvent *) appointmentFromString: (NSString *) _iCalString
|
|
||||||
{
|
|
||||||
iCalCalendar *calendar;
|
|
||||||
iCalEvent *appointment;
|
|
||||||
|
|
||||||
calendar = [iCalCalendar parseSingleFromSource: _iCalString];
|
|
||||||
appointment = (iCalEvent *) [calendar firstChildWithTag: @"vevent"];
|
|
||||||
|
|
||||||
return appointment;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* conflict management */
|
|
||||||
|
|
||||||
- (BOOL) containsConflict: (id) _apt
|
|
||||||
{
|
|
||||||
NSArray *attendees, *uids;
|
|
||||||
SOGoAppointmentFolder *groupCalendar;
|
|
||||||
NSArray *infos;
|
|
||||||
NSArray *ranges;
|
|
||||||
id folder;
|
|
||||||
|
|
||||||
[self logWithFormat:@"search from %@ to %@",
|
|
||||||
[_apt startDate], [_apt endDate]];
|
|
||||||
|
|
||||||
folder = [[self clientObject] container];
|
|
||||||
attendees = [_apt attendees];
|
|
||||||
uids = [folder uidsFromICalPersons:attendees];
|
|
||||||
if ([uids count] == 0) {
|
|
||||||
[self logWithFormat:@"Note: no UIDs selected."];
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
groupCalendar = [folder lookupGroupCalendarFolderForUIDs:uids
|
|
||||||
inContext:[self context]];
|
|
||||||
[self debugWithFormat:@"group calendar: %@", groupCalendar];
|
|
||||||
|
|
||||||
if (![groupCalendar respondsToSelector:@selector(fetchFreeBusyInfosFrom:to:)]) {
|
|
||||||
[self errorWithFormat:@"invalid folder to run freebusy query on!"];
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
infos = [groupCalendar fetchFreeBusyInfosFrom:[_apt startDate]
|
|
||||||
to:[_apt endDate]];
|
|
||||||
[self debugWithFormat:@" process: %d events", [infos count]];
|
|
||||||
|
|
||||||
ranges = [infos arrayByCreatingDateRangesFromObjectsWithStartDateKey: @"startDate"
|
|
||||||
andEndDateKey: @"endDate"];
|
|
||||||
ranges = [ranges arrayByCompactingContainedDateRanges];
|
|
||||||
[self debugWithFormat:@" blocked ranges: %@", ranges];
|
|
||||||
|
|
||||||
return [ranges count] != 0 ? YES : NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* actions */
|
|
||||||
|
|
||||||
- (id) testAction
|
|
||||||
{
|
|
||||||
/* for testing only */
|
|
||||||
WORequest *req;
|
|
||||||
iCalEvent *apt;
|
|
||||||
NSString *content;
|
|
||||||
|
|
||||||
req = [[self context] request];
|
|
||||||
apt = [self appointmentFromString: [self iCalString]];
|
|
||||||
[self saveValuesIntoAppointment:apt];
|
|
||||||
content = [[apt parent] versitString];
|
|
||||||
[self logWithFormat:@"%s -- iCal:\n%@",
|
|
||||||
__PRETTY_FUNCTION__,
|
|
||||||
content];
|
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id<WOActionResults>) defaultAction
|
/* template values */
|
||||||
|
- (iCalEvent *) event
|
||||||
{
|
{
|
||||||
NSString *ical;
|
return event;
|
||||||
|
|
||||||
/* load iCalendar file */
|
|
||||||
|
|
||||||
// TODO: can't we use [clientObject contentAsString]?
|
|
||||||
// ical = [[self clientObject] valueForKey:@"iCalString"];
|
|
||||||
ical = [[self clientObject] contentAsString];
|
|
||||||
if ([ical length] == 0) /* a new appointment */
|
|
||||||
ical = [self iCalStringTemplate];
|
|
||||||
|
|
||||||
[self setICalString:ical];
|
|
||||||
[self loadValuesFromAppointment: [self appointmentFromString: ical]];
|
|
||||||
|
|
||||||
// if (![self canEditComponent]) {
|
|
||||||
// /* TODO: we need proper ACLs */
|
|
||||||
// return [self redirectToLocation: [self completeURIForMethod: @"../view"]];
|
|
||||||
// }
|
|
||||||
return self;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id <WOActionResults>) saveAction
|
- (NSString *) saveURL
|
||||||
{
|
|
||||||
iCalEvent *apt;
|
|
||||||
iCalPerson *p;
|
|
||||||
id <WOActionResults> result;
|
|
||||||
NSString *content;
|
|
||||||
NSException *ex;
|
|
||||||
|
|
||||||
if (![self isWriteableClientObject]) {
|
|
||||||
/* return 400 == Bad Request */
|
|
||||||
return [NSException exceptionWithHTTPStatus:400
|
|
||||||
reason:@"method cannot be invoked on "
|
|
||||||
@"the specified object"];
|
|
||||||
}
|
|
||||||
|
|
||||||
apt = [self appointmentFromString: [self iCalString]];
|
|
||||||
if (apt == nil) {
|
|
||||||
NSString *s;
|
|
||||||
|
|
||||||
s = [self labelForKey:@"Invalid iCal data!"];
|
|
||||||
[self setErrorText:s];
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
[self saveValuesIntoAppointment:apt];
|
|
||||||
p = [apt findParticipantWithEmail:[self emailForUser]];
|
|
||||||
if (p) {
|
|
||||||
[p setParticipationStatus:iCalPersonPartStatAccepted];
|
|
||||||
}
|
|
||||||
|
|
||||||
if ([self checkForConflicts]) {
|
|
||||||
if ([self containsConflict:apt]) {
|
|
||||||
NSString *s;
|
|
||||||
|
|
||||||
s = [self labelForKey:@"Conflicts found!"];
|
|
||||||
[self setErrorText:s];
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
content = [[apt parent] versitString];
|
|
||||||
// [apt release]; apt = nil;
|
|
||||||
|
|
||||||
if (content == nil) {
|
|
||||||
NSString *s;
|
|
||||||
|
|
||||||
s = [self labelForKey:@"Could not create iCal data!"];
|
|
||||||
[self setErrorText:s];
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
ex = [[self clientObject] saveContentString:content];
|
|
||||||
if (ex != nil) {
|
|
||||||
[self setErrorText:[ex reason]];
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ([[[[self context] request] formValueForKey: @"nojs"] intValue])
|
|
||||||
result = [self redirectToLocation: [self applicationPath]];
|
|
||||||
else
|
|
||||||
result = [self jsCloseWithRefreshMethod: @"refreshAppointmentsAndDisplay()"];
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSString *) saveUrl
|
|
||||||
{
|
{
|
||||||
return [NSString stringWithFormat: @"%@/saveAsAppointment",
|
return [NSString stringWithFormat: @"%@/saveAsAppointment",
|
||||||
[[self clientObject] baseURL]];
|
[[self clientObject] baseURL]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id) acceptAction
|
- (NSString *) _toolbarForCalObject
|
||||||
{
|
{
|
||||||
return [self acceptOrDeclineAction:YES];
|
SOGoUser *currentUser;
|
||||||
|
SOGoAppointmentObject *clientObject;
|
||||||
|
NSString *filename, *email;
|
||||||
|
iCalPerson *person;
|
||||||
|
iCalPersonPartStat participationStatus;
|
||||||
|
|
||||||
|
clientObject = [self clientObject];
|
||||||
|
currentUser = [[self context] activeUser];
|
||||||
|
email = [currentUser email];
|
||||||
|
if ([clientObject isOrganizer: email
|
||||||
|
orOwner: [currentUser login]])
|
||||||
|
filename = @"SOGoAppointmentObject.toolbar";
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ([clientObject isParticipant: email])
|
||||||
|
{
|
||||||
|
person = [[clientObject component: NO] findParticipantWithEmail: email];
|
||||||
|
participationStatus = [person participationStatus];
|
||||||
|
if (participationStatus == iCalPersonPartStatAccepted)
|
||||||
|
filename = @"SOGoAppointmentObjectDecline.toolbar";
|
||||||
|
else if (participationStatus == iCalPersonPartStatDeclined)
|
||||||
|
filename = @"SOGoAppointmentObjectAccept.toolbar";
|
||||||
|
else
|
||||||
|
filename = @"SOGoAppointmentObjectAcceptOrDecline.toolbar";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
filename = @"";
|
||||||
|
}
|
||||||
|
|
||||||
|
return filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id) declineAction
|
- (NSString *) toolbar
|
||||||
{
|
{
|
||||||
return [self acceptOrDeclineAction:NO];
|
return ([self _toolbarForCalObject]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: add tentatively
|
/* icalendar values */
|
||||||
|
- (BOOL) isAllDay
|
||||||
- (id) acceptOrDeclineAction: (BOOL) _accept
|
|
||||||
{
|
{
|
||||||
// TODO: this should live in the SoObjects
|
return NO;
|
||||||
NSException *ex;
|
|
||||||
|
|
||||||
if ((ex = [self validateObjectForStatusChange]) != nil)
|
|
||||||
return ex;
|
|
||||||
|
|
||||||
ex = [[self clientObject] changeParticipationStatus:
|
|
||||||
_accept ? @"ACCEPTED" : @"DECLINED"
|
|
||||||
inContext:[self context]];
|
|
||||||
if (ex != nil) return ex;
|
|
||||||
|
|
||||||
return self;
|
|
||||||
// return [self redirectToLocation: [self completeURIForMethod: @"../view"]];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@end /* UIxAppointmentEditor */
|
- (void) setIsAllDay: (BOOL) newIsAllDay
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) setAptStartDate: (NSCalendarDate *) newAptStartDate
|
||||||
|
{
|
||||||
|
ASSIGN (aptStartDate, newAptStartDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSCalendarDate *) aptStartDate
|
||||||
|
{
|
||||||
|
return aptStartDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) setAptEndDate: (NSCalendarDate *) newAptEndDate
|
||||||
|
{
|
||||||
|
ASSIGN (aptEndDate, newAptEndDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSCalendarDate *) aptEndDate
|
||||||
|
{
|
||||||
|
return aptEndDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSArray *) repeatList
|
||||||
|
{
|
||||||
|
static NSArray *repeatItems = nil;
|
||||||
|
|
||||||
|
if (!repeatItems)
|
||||||
|
{
|
||||||
|
repeatItems = [NSArray arrayWithObjects: @"DAILY",
|
||||||
|
@"WEEKLY",
|
||||||
|
@"BI-WEEKLY",
|
||||||
|
@"EVERY WEEKDAY",
|
||||||
|
@"MONTHLY",
|
||||||
|
@"YEARLY",
|
||||||
|
@"-",
|
||||||
|
@"CUSTOM",
|
||||||
|
nil];
|
||||||
|
[repeatItems retain];
|
||||||
|
}
|
||||||
|
|
||||||
|
return repeatItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *) itemRepeatText
|
||||||
|
{
|
||||||
|
NSString *text;
|
||||||
|
|
||||||
|
if ([item isEqualToString: @"-"])
|
||||||
|
text = item;
|
||||||
|
else
|
||||||
|
text = [self labelForKey: [NSString stringWithFormat: @"repeat_%@", item]];
|
||||||
|
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) setItem: (NSString *) newItem
|
||||||
|
{
|
||||||
|
item = newItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *) item
|
||||||
|
{
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSArray *) reminderList
|
||||||
|
{
|
||||||
|
static NSArray *reminderItems = nil;
|
||||||
|
|
||||||
|
if (!reminderItems)
|
||||||
|
{
|
||||||
|
reminderItems = [NSArray arrayWithObjects: @"5_MINUTES_BEFORE",
|
||||||
|
@"10_MINUTES_BEFORE",
|
||||||
|
@"15_MINUTES_BEFORE",
|
||||||
|
@"30_MINUTES_BEFORE",
|
||||||
|
@"45_MINUTES_BEFORE",
|
||||||
|
@"-",
|
||||||
|
@"1_HOUR_BEFORE",
|
||||||
|
@"2_HOURS_BEFORE",
|
||||||
|
@"5_HOURS_BEFORE",
|
||||||
|
@"15_HOURS_BEFORE",
|
||||||
|
@"-",
|
||||||
|
@"1_DAY_BEFORE",
|
||||||
|
@"2_DAYS_BEFORE",
|
||||||
|
@"1_WEEK_BEFORE",
|
||||||
|
@"-",
|
||||||
|
@"CUSTOM",
|
||||||
|
nil];
|
||||||
|
[reminderItems retain];
|
||||||
|
}
|
||||||
|
|
||||||
|
return reminderItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
// - (void) setReminder: (NSString *) reminder
|
||||||
|
// {
|
||||||
|
// ASSIGN(reminder, _reminder);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// - (NSString *) reminder
|
||||||
|
// {
|
||||||
|
// return reminder;
|
||||||
|
// }
|
||||||
|
|
||||||
|
- (NSString *) itemReminderText
|
||||||
|
{
|
||||||
|
NSString *text;
|
||||||
|
|
||||||
|
if ([item isEqualToString: @"-"])
|
||||||
|
text = item;
|
||||||
|
else
|
||||||
|
text = [self labelForKey: [NSString stringWithFormat: @"reminder_%@", item]];
|
||||||
|
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *) repeat
|
||||||
|
{
|
||||||
|
return @"";
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) setRepeat: (NSString *) newRepeat
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *) reminder
|
||||||
|
{
|
||||||
|
return @"";
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) setReminder: (NSString *) newReminder
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/* actions */
|
||||||
|
- (NSCalendarDate *) newStartDate
|
||||||
|
{
|
||||||
|
NSCalendarDate *newStartDate, *now;
|
||||||
|
int hour;
|
||||||
|
|
||||||
|
newStartDate = [self selectedDate];
|
||||||
|
if ([[self queryParameterForKey: @"hm"] length] == 0)
|
||||||
|
{
|
||||||
|
now = [NSCalendarDate calendarDate];
|
||||||
|
[now setTimeZone: [[self clientObject] userTimeZone]];
|
||||||
|
if ([now isDateOnSameDay: newStartDate])
|
||||||
|
{
|
||||||
|
hour = [now hourOfDay];
|
||||||
|
if (hour < 8)
|
||||||
|
newStartDate = [now hour: 8 minute: 0];
|
||||||
|
else if (hour > 18)
|
||||||
|
newStartDate = [[now tomorrow] hour: 8 minute: 0];
|
||||||
|
else
|
||||||
|
newStartDate = now;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
newStartDate = [newStartDate hour: 8 minute: 0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return newStartDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id <WOActionResults>) defaultAction
|
||||||
|
{
|
||||||
|
NSCalendarDate *startDate, *endDate;
|
||||||
|
NSString *duration;
|
||||||
|
unsigned int minutes;
|
||||||
|
|
||||||
|
event = (iCalEvent *) [[self clientObject] component: NO];
|
||||||
|
if (event)
|
||||||
|
{
|
||||||
|
startDate = [event startDate];
|
||||||
|
endDate = [event endDate];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
startDate = [self newStartDate];
|
||||||
|
duration = [self queryParameterForKey:@"dur"];
|
||||||
|
if ([duration length] > 0)
|
||||||
|
minutes = [duration intValue];
|
||||||
|
else
|
||||||
|
minutes = 60;
|
||||||
|
endDate
|
||||||
|
= [startDate dateByAddingYears: 0 months: 0 days: 0
|
||||||
|
hours: 0 minutes: minutes seconds: 0];
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSIGN (aptStartDate, startDate);
|
||||||
|
ASSIGN (aptEndDate, endDate);
|
||||||
|
|
||||||
|
/* here comes the code for initializing repeat, reminder and isAllDay... */
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id <WOActionResults>) newAction
|
||||||
|
{
|
||||||
|
NSString *objectId, *method, *uri;
|
||||||
|
id <WOActionResults> result;
|
||||||
|
Class clientKlazz;
|
||||||
|
|
||||||
|
clientKlazz = [[self clientObject] class];
|
||||||
|
objectId = [clientKlazz globallyUniqueObjectId];
|
||||||
|
if ([objectId length] > 0)
|
||||||
|
{
|
||||||
|
method = [NSString stringWithFormat:@"%@/Calendar/%@/editAsAppointment",
|
||||||
|
[self userFolderPath], objectId];
|
||||||
|
uri = [self completeHrefForMethod: method];
|
||||||
|
result = [self redirectToLocation: uri];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
result = [NSException exceptionWithHTTPStatus: 500 /* Internal Error */
|
||||||
|
reason: @"could not create a unique ID"];
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id <WOActionResults>) saveAction
|
||||||
|
{
|
||||||
|
SOGoAppointmentObject *clientObject;
|
||||||
|
NSString *iCalString;
|
||||||
|
|
||||||
|
clientObject = [self clientObject];
|
||||||
|
iCalString = [[clientObject calendar: NO] versitString];
|
||||||
|
[clientObject saveContentString: iCalString];
|
||||||
|
|
||||||
|
return [self jsCloseWithRefreshMethod: @"refreshAppointmentsAndDisplay()"];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL) shouldTakeValuesFromRequest: (WORequest *) request
|
||||||
|
inContext: (WOContext*) context
|
||||||
|
{
|
||||||
|
return ([[self clientObject] isKindOfClass: [SOGoAppointmentObject class]]
|
||||||
|
&& [[request method] isEqualToString: @"POST"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) takeValuesFromRequest: (WORequest *) _rq
|
||||||
|
inContext: (WOContext *) _ctx
|
||||||
|
{
|
||||||
|
SOGoAppointmentObject *clientObject;
|
||||||
|
|
||||||
|
clientObject = [self clientObject];
|
||||||
|
event = (iCalEvent *) [clientObject component: YES];
|
||||||
|
|
||||||
|
[super takeValuesFromRequest: _rq inContext: _ctx];
|
||||||
|
|
||||||
|
[event setStartDate: aptStartDate];
|
||||||
|
[event setEndDate: aptEndDate];
|
||||||
|
if ([clientObject isNew])
|
||||||
|
[event setTransparency: @"OPAQUE"];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
|
@ -37,33 +37,36 @@
|
||||||
|
|
||||||
@interface UIxComponentEditor : UIxComponent
|
@interface UIxComponentEditor : UIxComponent
|
||||||
{
|
{
|
||||||
NSString *iCalString;
|
iCalRepeatableEntityObject *component;
|
||||||
NSString *errorText;
|
|
||||||
id item;
|
id item;
|
||||||
|
|
||||||
|
NSString *saveURL;
|
||||||
|
|
||||||
/* individual values */
|
/* individual values */
|
||||||
NSCalendarDate *startDate;
|
|
||||||
NSCalendarDate *cycleUntilDate;
|
NSCalendarDate *cycleUntilDate;
|
||||||
NSString *title;
|
NSString *title;
|
||||||
NSString *location;
|
NSString *location;
|
||||||
NSString *comment;
|
NSString *comment;
|
||||||
NSString *url;
|
NSString *url;
|
||||||
iCalPerson *organizer;
|
iCalPerson *organizer;
|
||||||
NSArray *participants; /* array of iCalPerson's */
|
|
||||||
NSArray *resources; /* array of iCalPerson's */
|
|
||||||
NSString *priority;
|
NSString *priority;
|
||||||
NSString *privacy;
|
NSString *privacy;
|
||||||
NSString *status;
|
NSString *status;
|
||||||
NSArray *categories;
|
NSArray *categories;
|
||||||
BOOL checkForConflicts; /* default: NO */
|
|
||||||
NSDictionary *cycle;
|
NSDictionary *cycle;
|
||||||
NSString *cycleEnd;
|
NSString *cycleEnd;
|
||||||
NSString *componentOwner;
|
NSString *componentOwner;
|
||||||
|
|
||||||
BOOL componentLoaded;
|
NSString *attendeesNames;
|
||||||
|
NSString *attendeesEmails;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSArray *) categoryItems;
|
- (void) setComponent: (iCalRepeatableEntityObject *) newComponent;
|
||||||
|
|
||||||
|
- (void) setSaveURL: (NSString *) newSaveURL;
|
||||||
|
- (NSString *) saveURL;
|
||||||
|
|
||||||
|
- (NSArray *) categoryList;
|
||||||
- (void) setCategories: (NSArray *) _categories;
|
- (void) setCategories: (NSArray *) _categories;
|
||||||
- (NSArray *) categories;
|
- (NSArray *) categories;
|
||||||
- (NSString *) itemCategoryText;
|
- (NSString *) itemCategoryText;
|
||||||
|
@ -87,18 +90,6 @@
|
||||||
- (id) item;
|
- (id) item;
|
||||||
- (NSString *) itemPriorityText;
|
- (NSString *) itemPriorityText;
|
||||||
|
|
||||||
- (void) setErrorText: (NSString *) _txt;
|
|
||||||
- (NSString *) errorText;
|
|
||||||
- (BOOL) hasErrorText;
|
|
||||||
|
|
||||||
- (void) setICalString: (NSString *) _s;
|
|
||||||
- (NSString *) iCalString;
|
|
||||||
|
|
||||||
- (NSCalendarDate *) newStartDate;
|
|
||||||
|
|
||||||
- (void) setStartDate: (NSCalendarDate *) _date;
|
|
||||||
- (NSCalendarDate *) startDate;
|
|
||||||
|
|
||||||
- (void) setTitle: (NSString *) _value;
|
- (void) setTitle: (NSString *) _value;
|
||||||
- (NSString *) title;
|
- (NSString *) title;
|
||||||
|
|
||||||
|
@ -111,14 +102,11 @@
|
||||||
- (void) setUrl: (NSString *) _url;
|
- (void) setUrl: (NSString *) _url;
|
||||||
- (NSString *) url;
|
- (NSString *) url;
|
||||||
|
|
||||||
- (void) setParticipants: (NSArray *) _parts;
|
- (void) setAttendeesNames: (NSString *) newAttendeesNames;
|
||||||
- (NSArray *) participants;
|
- (NSString *) attendeesNames;
|
||||||
|
|
||||||
- (void) setResources: (NSArray *) _res;
|
- (void) setAttendeesEmails: (NSString *) newAttendeesEmails;
|
||||||
- (NSArray *) resources;
|
- (NSString *) attendeesEmails;
|
||||||
|
|
||||||
- (void) setCheckForConflicts: (BOOL) _checkForConflicts;
|
|
||||||
- (BOOL) checkForConflicts;
|
|
||||||
|
|
||||||
- (NSArray *) cycles;
|
- (NSArray *) cycles;
|
||||||
- (void) setCycle: (NSDictionary *) _cycle;
|
- (void) setCycle: (NSDictionary *) _cycle;
|
||||||
|
@ -150,17 +138,12 @@
|
||||||
- (BOOL) isWriteableClientObject;
|
- (BOOL) isWriteableClientObject;
|
||||||
- (NSException *) validateObjectForStatusChange;
|
- (NSException *) validateObjectForStatusChange;
|
||||||
|
|
||||||
/* subclasses */
|
|
||||||
- (void) loadValuesFromComponent: (iCalRepeatableEntityObject *) component;
|
|
||||||
|
|
||||||
- (NSString *) iCalStringTemplate;
|
|
||||||
- (NSString *) iCalParticipantsAndResourcesStringFromQueryParameters;
|
- (NSString *) iCalParticipantsAndResourcesStringFromQueryParameters;
|
||||||
- (NSString *) iCalParticipantsStringFromQueryParameters;
|
- (NSString *) iCalParticipantsStringFromQueryParameters;
|
||||||
- (NSString *) iCalResourcesStringFromQueryParameters;
|
- (NSString *) iCalResourcesStringFromQueryParameters;
|
||||||
- (NSString *) iCalStringFromQueryParameter: (NSString *) _qp
|
- (NSString *) iCalStringFromQueryParameter: (NSString *) _qp
|
||||||
format: (NSString *) _format;
|
format: (NSString *) _format;
|
||||||
- (NSString *) iCalOrganizerString;
|
- (NSString *) iCalOrganizerString;
|
||||||
- (NSString *) toolbar;
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
|
@ -55,11 +55,12 @@
|
||||||
{
|
{
|
||||||
if ((self = [super init]))
|
if ((self = [super init]))
|
||||||
{
|
{
|
||||||
|
component = nil;
|
||||||
[self setPrivacy: @"PUBLIC"];
|
[self setPrivacy: @"PUBLIC"];
|
||||||
[self setCheckForConflicts: NO];
|
|
||||||
[self setIsCycleEndNever];
|
[self setIsCycleEndNever];
|
||||||
componentOwner = @"";
|
componentOwner = @"";
|
||||||
componentLoaded = NO;
|
attendeesNames = nil;
|
||||||
|
attendeesEmails = nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
@ -67,31 +68,102 @@
|
||||||
|
|
||||||
- (void) dealloc
|
- (void) dealloc
|
||||||
{
|
{
|
||||||
[iCalString release];
|
|
||||||
[errorText release];
|
|
||||||
[item release];
|
[item release];
|
||||||
[startDate release];
|
|
||||||
[cycleUntilDate release];
|
[cycleUntilDate release];
|
||||||
[title release];
|
[title release];
|
||||||
[location release];
|
[location release];
|
||||||
[organizer release];
|
[organizer release];
|
||||||
[comment release];
|
[comment release];
|
||||||
[participants release];
|
|
||||||
[resources release];
|
|
||||||
[priority release];
|
[priority release];
|
||||||
[categories release];
|
[categories release];
|
||||||
[cycle release];
|
[cycle release];
|
||||||
[cycleEnd release];
|
[cycleEnd release];
|
||||||
[url release];
|
[url release];
|
||||||
|
[attendeesNames release];
|
||||||
|
[attendeesEmails release];
|
||||||
|
|
||||||
[super dealloc];
|
[super dealloc];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) _loadAttendees
|
||||||
|
{
|
||||||
|
NSEnumerator *attendees;
|
||||||
|
iCalPerson *currentAttendee;
|
||||||
|
NSMutableString *names, *emails;
|
||||||
|
|
||||||
|
names = [NSMutableString new];
|
||||||
|
emails = [NSMutableString new];
|
||||||
|
|
||||||
|
attendees = [[component attendees] objectEnumerator];
|
||||||
|
currentAttendee = [attendees nextObject];
|
||||||
|
while (currentAttendee)
|
||||||
|
{
|
||||||
|
NSLog (@"currentCN: %@", [currentAttendee cn]);
|
||||||
|
[names appendFormat: @"%@,", [currentAttendee cn]];
|
||||||
|
[emails appendFormat: @"%@,", [currentAttendee rfc822Email]];
|
||||||
|
currentAttendee = [attendees nextObject];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ([names length] > 0)
|
||||||
|
{
|
||||||
|
ASSIGN (attendeesNames, [names substringToIndex: [names length] - 1]);
|
||||||
|
ASSIGN (attendeesEmails,
|
||||||
|
[emails substringToIndex: [emails length] - 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
[names release];
|
||||||
|
[emails release];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* warning: we use this method which will be triggered by the template system
|
||||||
|
when the page is instantiated, but we should find another and cleaner way of
|
||||||
|
doing this... for example, when the clientObject is set */
|
||||||
|
- (void) setComponent: (iCalRepeatableEntityObject *) newComponent
|
||||||
|
{
|
||||||
|
// iCalRecurrenceRule *rrule;
|
||||||
|
SOGoObject *co;
|
||||||
|
|
||||||
|
if (!component)
|
||||||
|
{
|
||||||
|
component = newComponent;
|
||||||
|
|
||||||
|
co = [self clientObject];
|
||||||
|
componentOwner = [co ownerInContext: nil];
|
||||||
|
|
||||||
|
ASSIGN (title, [component summary]);
|
||||||
|
ASSIGN (location, [component location]);
|
||||||
|
ASSIGN (comment, [component comment]);
|
||||||
|
ASSIGN (url, [[component url] absoluteString]);
|
||||||
|
ASSIGN (privacy, [component accessClass]);
|
||||||
|
ASSIGN (priority, [component priority]);
|
||||||
|
ASSIGN (status, [component status]);
|
||||||
|
ASSIGN (categories, [[component categories] commaSeparatedValues]);
|
||||||
|
ASSIGN (organizer, [component organizer]);
|
||||||
|
[self _loadAttendees];
|
||||||
|
}
|
||||||
|
// /* cycles */
|
||||||
|
// if ([component isRecurrent])
|
||||||
|
// {
|
||||||
|
// rrule = [[component recurrenceRules] objectAtIndex: 0];
|
||||||
|
// [self adjustCycleControlsForRRule: rrule];
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) setSaveURL: (NSString *) newSaveURL
|
||||||
|
{
|
||||||
|
saveURL = newSaveURL;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *) saveURL
|
||||||
|
{
|
||||||
|
return saveURL;
|
||||||
|
}
|
||||||
|
|
||||||
/* accessors */
|
/* accessors */
|
||||||
|
|
||||||
- (void) setItem: (id) _item
|
- (void) setItem: (id) _item
|
||||||
{
|
{
|
||||||
ASSIGN(item, _item);
|
ASSIGN (item, _item);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id) item
|
- (id) item
|
||||||
|
@ -114,34 +186,9 @@
|
||||||
return [self labelForKey: [NSString stringWithFormat: @"status_%@", item]];
|
return [self labelForKey: [NSString stringWithFormat: @"status_%@", item]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) setErrorText: (NSString *) _txt
|
|
||||||
{
|
|
||||||
ASSIGNCOPY(errorText, _txt);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSString *) errorText
|
|
||||||
{
|
|
||||||
return errorText;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL) hasErrorText
|
|
||||||
{
|
|
||||||
return [errorText length] > 0 ? YES : NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void) setStartDate: (NSCalendarDate *) _date
|
|
||||||
{
|
|
||||||
ASSIGN(startDate, _date);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSCalendarDate *) startDate
|
|
||||||
{
|
|
||||||
return startDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void) setTitle: (NSString *) _value
|
- (void) setTitle: (NSString *) _value
|
||||||
{
|
{
|
||||||
ASSIGNCOPY(title, _value);
|
ASSIGN (title, _value);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSString *) title
|
- (NSString *) title
|
||||||
|
@ -151,7 +198,7 @@
|
||||||
|
|
||||||
- (void) setUrl: (NSString *) _url
|
- (void) setUrl: (NSString *) _url
|
||||||
{
|
{
|
||||||
ASSIGNCOPY(url, _url);
|
ASSIGN (url, _url);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSString *) url
|
- (NSString *) url
|
||||||
|
@ -159,9 +206,29 @@
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void) setAttendeesNames: (NSString *) newAttendeesNames
|
||||||
|
{
|
||||||
|
ASSIGN (attendeesNames, newAttendeesNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *) attendeesNames
|
||||||
|
{
|
||||||
|
return attendeesNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) setAttendeesEmails: (NSString *) newAttendeesEmails
|
||||||
|
{
|
||||||
|
ASSIGN (attendeesEmails, newAttendeesEmails);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *) attendeesEmails
|
||||||
|
{
|
||||||
|
return attendeesEmails;
|
||||||
|
}
|
||||||
|
|
||||||
- (void) setLocation: (NSString *) _value
|
- (void) setLocation: (NSString *) _value
|
||||||
{
|
{
|
||||||
ASSIGNCOPY(location, _value);
|
ASSIGN (location, _value);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSString *) location
|
- (NSString *) location
|
||||||
|
@ -171,7 +238,7 @@
|
||||||
|
|
||||||
- (void) setComment: (NSString *) _value
|
- (void) setComment: (NSString *) _value
|
||||||
{
|
{
|
||||||
ASSIGNCOPY(comment, _value);
|
ASSIGN (comment, _value);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSString *) comment
|
- (NSString *) comment
|
||||||
|
@ -179,28 +246,34 @@
|
||||||
return comment;
|
return comment;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSArray *) categoryItems
|
- (NSArray *) categoryList
|
||||||
{
|
{
|
||||||
// TODO: make this configurable?
|
|
||||||
/*
|
|
||||||
Tasks categories will be modified as follow :
|
|
||||||
– by default (a simple logo or no logo at all),
|
|
||||||
– task,
|
|
||||||
– outside,
|
|
||||||
– meeting,
|
|
||||||
– holidays,
|
|
||||||
– phone.
|
|
||||||
*/
|
|
||||||
static NSArray *categoryItems = nil;
|
static NSArray *categoryItems = nil;
|
||||||
|
|
||||||
if (!categoryItems)
|
if (!categoryItems)
|
||||||
{
|
{
|
||||||
categoryItems = [NSArray arrayWithObjects: @"APPOINTMENT",
|
categoryItems = [NSArray arrayWithObjects: @"ANNIVERSARY",
|
||||||
@"NOT IN OFFICE",
|
@"BIRTHDAY",
|
||||||
@"MEETING",
|
@"BUSINESS",
|
||||||
@"HOLIDAY",
|
@"CALLS",
|
||||||
@"PHONE CALL",
|
@"CLIENTS",
|
||||||
nil];
|
@"COMPETITION",
|
||||||
|
@"CUSTOMER",
|
||||||
|
@"FAVORITES",
|
||||||
|
@"FOLLOW UP",
|
||||||
|
@"GIFTS",
|
||||||
|
@"HOLIDAYS",
|
||||||
|
@"IDEAS",
|
||||||
|
@"ISSUES",
|
||||||
|
@"MISCELLANEOUS",
|
||||||
|
@"PERSONAL",
|
||||||
|
@"PROJECTS",
|
||||||
|
@"PUBLIC HOLIDAY",
|
||||||
|
@"STATUS",
|
||||||
|
@"SUPPLIERS",
|
||||||
|
@"TRAVEL",
|
||||||
|
@"VACATION",
|
||||||
|
nil];
|
||||||
[categoryItems retain];
|
[categoryItems retain];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,7 +282,7 @@
|
||||||
|
|
||||||
- (void) setCategories: (NSArray *) _categories
|
- (void) setCategories: (NSArray *) _categories
|
||||||
{
|
{
|
||||||
ASSIGN(categories, _categories);
|
ASSIGN (categories, _categories);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSArray *) categories
|
- (NSArray *) categories
|
||||||
|
@ -219,7 +292,7 @@
|
||||||
|
|
||||||
- (NSString *) itemCategoryText
|
- (NSString *) itemCategoryText
|
||||||
{
|
{
|
||||||
return [[self labelForKey: item] stringByEscapingHTMLString];
|
return [self labelForKey: [NSString stringWithFormat: @"category_%@", item]];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* priorities */
|
/* priorities */
|
||||||
|
@ -234,7 +307,7 @@
|
||||||
|
|
||||||
if (!priorities)
|
if (!priorities)
|
||||||
{
|
{
|
||||||
priorities = [NSArray arrayWithObjects:@"0", @"5", @"1", nil];
|
priorities = [NSArray arrayWithObjects: @"0", @"5", @"1", nil];
|
||||||
[priorities retain];
|
[priorities retain];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,7 +316,7 @@
|
||||||
|
|
||||||
- (void) setPriority: (NSString *) _priority
|
- (void) setPriority: (NSString *) _priority
|
||||||
{
|
{
|
||||||
ASSIGN(priority, _priority);
|
ASSIGN (priority, _priority);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSString *) priority
|
- (NSString *) priority
|
||||||
|
@ -267,7 +340,7 @@
|
||||||
|
|
||||||
- (void) setPrivacy: (NSString *) _privacy
|
- (void) setPrivacy: (NSString *) _privacy
|
||||||
{
|
{
|
||||||
ASSIGN(privacy, _privacy);
|
ASSIGN (privacy, _privacy);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSString *) privacy
|
- (NSString *) privacy
|
||||||
|
@ -290,7 +363,7 @@
|
||||||
|
|
||||||
- (void) setStatus: (NSString *) _status
|
- (void) setStatus: (NSString *) _status
|
||||||
{
|
{
|
||||||
ASSIGN(status, _status);
|
ASSIGN (status, _status);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSString *) status
|
- (NSString *) status
|
||||||
|
@ -298,36 +371,6 @@
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) setParticipants: (NSArray *) _parts
|
|
||||||
{
|
|
||||||
ASSIGN(participants, _parts);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSArray *) participants
|
|
||||||
{
|
|
||||||
return participants;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void) setResources: (NSArray *) _res
|
|
||||||
{
|
|
||||||
ASSIGN(resources, _res);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSArray *) resources
|
|
||||||
{
|
|
||||||
return resources;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void) setCheckForConflicts: (BOOL) _checkForConflicts
|
|
||||||
{
|
|
||||||
checkForConflicts = _checkForConflicts;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL) checkForConflicts
|
|
||||||
{
|
|
||||||
return checkForConflicts;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSArray *) cycles
|
- (NSArray *) cycles
|
||||||
{
|
{
|
||||||
NSBundle *bundle;
|
NSBundle *bundle;
|
||||||
|
@ -337,7 +380,7 @@
|
||||||
if (!cycles)
|
if (!cycles)
|
||||||
{
|
{
|
||||||
bundle = [NSBundle bundleForClass:[self class]];
|
bundle = [NSBundle bundleForClass:[self class]];
|
||||||
path = [bundle pathForResource:@"cycles" ofType:@"plist"];
|
path = [bundle pathForResource: @"cycles" ofType: @"plist"];
|
||||||
NSAssert(path != nil, @"Cannot find cycles.plist!");
|
NSAssert(path != nil, @"Cannot find cycles.plist!");
|
||||||
cycles = [[NSArray arrayWithContentsOfFile:path] retain];
|
cycles = [[NSArray arrayWithContentsOfFile:path] retain];
|
||||||
NSAssert(cycles != nil, @"Cannot instantiate cycles from cycles.plist!");
|
NSAssert(cycles != nil, @"Cannot instantiate cycles from cycles.plist!");
|
||||||
|
@ -348,7 +391,7 @@
|
||||||
|
|
||||||
- (void) setCycle: (NSDictionary *) _cycle
|
- (void) setCycle: (NSDictionary *) _cycle
|
||||||
{
|
{
|
||||||
ASSIGN(cycle, _cycle);
|
ASSIGN (cycle, _cycle);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSDictionary *) cycle
|
- (NSDictionary *) cycle
|
||||||
|
@ -365,21 +408,21 @@
|
||||||
{
|
{
|
||||||
NSString *key;
|
NSString *key;
|
||||||
|
|
||||||
key = [(NSDictionary *)item objectForKey:@"label"];
|
key = [(NSDictionary *)item objectForKey: @"label"];
|
||||||
|
|
||||||
return [self labelForKey:key];
|
return [self labelForKey:key];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) setCycleUntilDate: (NSCalendarDate *) _cycleUntilDate
|
- (void) setCycleUntilDate: (NSCalendarDate *) _cycleUntilDate
|
||||||
{
|
{
|
||||||
NSCalendarDate *until;
|
// NSCalendarDate *until;
|
||||||
|
|
||||||
/* copy hour/minute/second from startDate */
|
// /* copy hour/minute/second from startDate */
|
||||||
until = [_cycleUntilDate hour: [startDate hourOfDay]
|
// until = [_cycleUntilDate hour: [startDate hourOfDay]
|
||||||
minute: [startDate minuteOfHour]
|
// minute: [startDate minuteOfHour]
|
||||||
second: [startDate secondOfMinute]];
|
// second: [startDate secondOfMinute]];
|
||||||
[until setTimeZone: [startDate timeZone]];
|
// [until setTimeZone: [startDate timeZone]];
|
||||||
ASSIGN(cycleUntilDate, until);
|
// ASSIGN (cycleUntilDate, until);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSCalendarDate *) cycleUntilDate
|
- (NSCalendarDate *) cycleUntilDate
|
||||||
|
@ -394,7 +437,7 @@
|
||||||
|
|
||||||
if (![self hasCycle])
|
if (![self hasCycle])
|
||||||
return nil;
|
return nil;
|
||||||
ruleRep = [cycle objectForKey:@"rule"];
|
ruleRep = [cycle objectForKey: @"rule"];
|
||||||
rule = [iCalRecurrenceRule recurrenceRuleWithICalRepresentation:ruleRep];
|
rule = [iCalRecurrenceRule recurrenceRuleWithICalRepresentation:ruleRep];
|
||||||
|
|
||||||
if (cycleUntilDate && [self isCycleEndUntil])
|
if (cycleUntilDate && [self isCycleEndUntil])
|
||||||
|
@ -405,20 +448,20 @@
|
||||||
|
|
||||||
- (void) adjustCycleControlsForRRule: (iCalRecurrenceRule *) _rrule
|
- (void) adjustCycleControlsForRRule: (iCalRecurrenceRule *) _rrule
|
||||||
{
|
{
|
||||||
NSDictionary *c;
|
// NSDictionary *c;
|
||||||
NSCalendarDate *until;
|
// NSCalendarDate *until;
|
||||||
|
|
||||||
c = [self cycleMatchingRRule:_rrule];
|
// c = [self cycleMatchingRRule:_rrule];
|
||||||
[self setCycle:c];
|
// [self setCycle:c];
|
||||||
|
|
||||||
until = [[[_rrule untilDate] copy] autorelease];
|
// until = [[[_rrule untilDate] copy] autorelease];
|
||||||
if (!until)
|
// if (!until)
|
||||||
until = startDate;
|
// until = startDate;
|
||||||
else
|
// else
|
||||||
[self setIsCycleEndUntil];
|
// [self setIsCycleEndUntil];
|
||||||
|
|
||||||
[until setTimeZone:[[self clientObject] userTimeZone]];
|
// [until setTimeZone:[[self clientObject] userTimeZone]];
|
||||||
[self setCycleUntilDate:until];
|
// [self setCycleUntilDate:until];
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -448,11 +491,11 @@
|
||||||
NSString *cr;
|
NSString *cr;
|
||||||
|
|
||||||
c = [cycles objectAtIndex:i];
|
c = [cycles objectAtIndex:i];
|
||||||
cr = [c objectForKey:@"rule"];
|
cr = [c objectForKey: @"rule"];
|
||||||
if ([cr isEqualToString:cycleRep])
|
if ([cr isEqualToString:cycleRep])
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
[self warnWithFormat:@"No default cycle for rrule found! -> %@", _rrule];
|
[self warnWithFormat: @"No default cycle for rrule found! -> %@", _rrule];
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -473,7 +516,7 @@
|
||||||
|
|
||||||
- (void) setCycleEnd: (NSString *) _cycleEnd
|
- (void) setCycleEnd: (NSString *) _cycleEnd
|
||||||
{
|
{
|
||||||
ASSIGNCOPY(cycleEnd, _cycleEnd);
|
ASSIGN (cycleEnd, _cycleEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSString *) cycleEnd
|
- (NSString *) cycleEnd
|
||||||
|
@ -483,18 +526,17 @@
|
||||||
|
|
||||||
- (BOOL) isCycleEndUntil
|
- (BOOL) isCycleEndUntil
|
||||||
{
|
{
|
||||||
return (cycleEnd &&
|
return (cycleEnd && [cycleEnd isEqualToString: @"cycle_end_until"]);
|
||||||
[cycleEnd isEqualToString:@"cycle_end_until"]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) setIsCycleEndUntil
|
- (void) setIsCycleEndUntil
|
||||||
{
|
{
|
||||||
[self setCycleEnd:@"cycle_end_until"];
|
[self setCycleEnd: @"cycle_end_until"];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) setIsCycleEndNever
|
- (void) setIsCycleEndNever
|
||||||
{
|
{
|
||||||
[self setCycleEnd:@"cycle_end_never"];
|
[self setCycleEnd: @"cycle_end_never"];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* helpers */
|
/* helpers */
|
||||||
|
@ -517,13 +559,13 @@
|
||||||
uri = [[[self context] request] uri];
|
uri = [[[self context] request] uri];
|
||||||
|
|
||||||
/* first: identify query parameters */
|
/* first: identify query parameters */
|
||||||
r = [uri rangeOfString:@"?" options:NSBackwardsSearch];
|
r = [uri rangeOfString: @"?" options:NSBackwardsSearch];
|
||||||
if (r.length > 0)
|
if (r.length > 0)
|
||||||
uri = [uri substringToIndex:r.location];
|
uri = [uri substringToIndex:r.location];
|
||||||
|
|
||||||
/* next: append trailing slash */
|
/* next: append trailing slash */
|
||||||
if (![uri hasSuffix:@"/"])
|
if (![uri hasSuffix: @"/"])
|
||||||
uri = [uri stringByAppendingString:@"/"];
|
uri = [uri stringByAppendingString: @"/"];
|
||||||
|
|
||||||
/* next: append method */
|
/* next: append method */
|
||||||
uri = [uri stringByAppendingString:_method];
|
uri = [uri stringByAppendingString:_method];
|
||||||
|
@ -535,13 +577,7 @@
|
||||||
- (BOOL) isWriteableClientObject
|
- (BOOL) isWriteableClientObject
|
||||||
{
|
{
|
||||||
return [[self clientObject]
|
return [[self clientObject]
|
||||||
respondsToSelector:@selector(saveContentString:)];
|
respondsToSelector: @selector(saveContentString:)];
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL) shouldTakeValuesFromRequest: (WORequest *) _rq
|
|
||||||
inContext: (WOContext*) _c
|
|
||||||
{
|
|
||||||
return YES;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL) containsConflict: (id) _component
|
- (BOOL) containsConflict: (id) _component
|
||||||
|
@ -593,81 +629,6 @@
|
||||||
: @"visibility: hidden;");
|
: @"visibility: hidden;");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* subclasses */
|
|
||||||
- (NSCalendarDate *) newStartDate
|
|
||||||
{
|
|
||||||
NSCalendarDate *newStartDate, *now;
|
|
||||||
int hour;
|
|
||||||
|
|
||||||
newStartDate = [self selectedDate];
|
|
||||||
if ([[self queryParameterForKey: @"hm"] length] == 0)
|
|
||||||
{
|
|
||||||
now = [NSCalendarDate calendarDate];
|
|
||||||
[now setTimeZone: [[self clientObject] userTimeZone]];
|
|
||||||
if ([now isDateOnSameDay: newStartDate])
|
|
||||||
{
|
|
||||||
hour = [now hourOfDay];
|
|
||||||
if (hour < 8)
|
|
||||||
newStartDate = [now hour: 8 minute: 0];
|
|
||||||
else if (hour > 18)
|
|
||||||
newStartDate = [[now tomorrow] hour: 8 minute: 0];
|
|
||||||
else
|
|
||||||
newStartDate = now;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
newStartDate = [newStartDate hour: 8 minute: 0];
|
|
||||||
}
|
|
||||||
|
|
||||||
return newStartDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void) loadValuesFromComponent: (iCalRepeatableEntityObject *) component
|
|
||||||
{
|
|
||||||
iCalRecurrenceRule *rrule;
|
|
||||||
NSTimeZone *uTZ;
|
|
||||||
SOGoObject *co;
|
|
||||||
|
|
||||||
co = [self clientObject];
|
|
||||||
componentOwner = [co ownerInContext: nil];
|
|
||||||
componentLoaded = YES;
|
|
||||||
|
|
||||||
startDate = [component startDate];
|
|
||||||
// if ((startDate = [component startDate]) == nil)
|
|
||||||
// startDate = [[NSCalendarDate date] hour:11 minute:0];
|
|
||||||
uTZ = [co userTimeZone];
|
|
||||||
if (startDate)
|
|
||||||
{
|
|
||||||
[startDate setTimeZone: uTZ];
|
|
||||||
[startDate retain];
|
|
||||||
}
|
|
||||||
|
|
||||||
title = [[component summary] copy];
|
|
||||||
location = [[component location] copy];
|
|
||||||
comment = [[component comment] copy];
|
|
||||||
url = [[[component url] absoluteString] copy];
|
|
||||||
privacy = [[component accessClass] copy];
|
|
||||||
priority = [[component priority] copy];
|
|
||||||
status = [[component status] copy];
|
|
||||||
categories = [[[component categories] commaSeparatedValues] retain];
|
|
||||||
organizer = [[component organizer] retain];
|
|
||||||
participants = [[component participants] retain];
|
|
||||||
resources = [[component resources] retain];
|
|
||||||
|
|
||||||
/* cycles */
|
|
||||||
if ([component isRecurrent])
|
|
||||||
{
|
|
||||||
rrule = [[component recurrenceRules] objectAtIndex: 0];
|
|
||||||
[self adjustCycleControlsForRRule: rrule];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSString *) iCalStringTemplate
|
|
||||||
{
|
|
||||||
[self subclassResponsibility: _cmd];
|
|
||||||
|
|
||||||
return @"";
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSString *) iCalParticipantsAndResourcesStringFromQueryParameters
|
- (NSString *) iCalParticipantsAndResourcesStringFromQueryParameters
|
||||||
{
|
{
|
||||||
NSString *s;
|
NSString *s;
|
||||||
|
@ -709,7 +670,7 @@
|
||||||
NSArray *es;
|
NSArray *es;
|
||||||
unsigned i, count;
|
unsigned i, count;
|
||||||
|
|
||||||
es = [s componentsSeparatedByString:@","];
|
es = [s componentsSeparatedByString: @","];
|
||||||
count = [es count];
|
count = [es count];
|
||||||
for(i = 0; i < count; i++) {
|
for(i = 0; i < count; i++) {
|
||||||
NSString *email, *cn;
|
NSString *email, *cn;
|
||||||
|
@ -728,13 +689,6 @@
|
||||||
[self cnForUser], [self emailForUser]];
|
[self cnForUser], [self emailForUser]];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSString *) saveUrl
|
|
||||||
{
|
|
||||||
[self subclassResponsibility: _cmd];
|
|
||||||
|
|
||||||
return @"";
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSException *) validateObjectForStatusChange
|
- (NSException *) validateObjectForStatusChange
|
||||||
{
|
{
|
||||||
id co;
|
id co;
|
||||||
|
@ -751,16 +705,6 @@
|
||||||
|
|
||||||
/* contact editor compatibility */
|
/* contact editor compatibility */
|
||||||
|
|
||||||
- (void) setICalString: (NSString *) _s
|
|
||||||
{
|
|
||||||
ASSIGNCOPY(iCalString, _s);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSString *) iCalString
|
|
||||||
{
|
|
||||||
return iCalString;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSArray *) availableCalendars
|
- (NSArray *) availableCalendars
|
||||||
{
|
{
|
||||||
NSEnumerator *rawContacts;
|
NSEnumerator *rawContacts;
|
||||||
|
@ -807,58 +751,58 @@
|
||||||
return classes;
|
return classes;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSString *) _toolbarForCalObject: (iCalEntityObject *) calObject
|
- (void) _handleAttendeesEdition
|
||||||
{
|
{
|
||||||
NSString *filename, *myEmail;
|
NSArray *names, *emails;
|
||||||
iCalPerson *person;
|
NSMutableArray *newAttendees;
|
||||||
NSEnumerator *persons;
|
unsigned int count, max;
|
||||||
iCalPersonPartStat myParticipationStatus;
|
NSString *currentEmail;
|
||||||
BOOL found;
|
iCalPerson *currentAttendee;
|
||||||
|
|
||||||
myEmail = [[[self context] activeUser] email];
|
newAttendees = [NSMutableArray new];
|
||||||
if ([[organizer rfc822Email] isEqualToString: myEmail])
|
names = [attendeesNames componentsSeparatedByString: @","];
|
||||||
filename = @"SOGoAppointmentObject.toolbar";
|
emails = [attendeesEmails componentsSeparatedByString: @","];
|
||||||
else
|
max = [emails count];
|
||||||
|
for (count = 0; count < max; count++)
|
||||||
{
|
{
|
||||||
filename = @"";
|
currentEmail = [emails objectAtIndex: count];
|
||||||
found = NO;
|
currentAttendee = [component findParticipantWithEmail: currentEmail];
|
||||||
persons = [participants objectEnumerator];
|
if (!currentAttendee)
|
||||||
person = [persons nextObject];
|
{
|
||||||
while (person && !found)
|
currentAttendee = [iCalPerson elementWithTag: @"attendee"];
|
||||||
if ([[person rfc822Email] isEqualToString: myEmail])
|
[currentAttendee setCn: [names objectAtIndex: count]];
|
||||||
{
|
[currentAttendee setEmail: currentEmail];
|
||||||
found = YES;
|
[currentAttendee setRole: @"REQ-PARTICIPANT"];
|
||||||
myParticipationStatus = [person participationStatus];
|
[currentAttendee
|
||||||
if (myParticipationStatus == iCalPersonPartStatAccepted)
|
setParticipationStatus: iCalPersonPartStatNeedsAction];
|
||||||
filename = @"SOGoAppointmentObjectDecline.toolbar";
|
}
|
||||||
else if (myParticipationStatus == iCalPersonPartStatDeclined)
|
[newAttendees addObject: currentAttendee];
|
||||||
filename = @"SOGoAppointmentObjectAccept.toolbar";
|
|
||||||
else
|
|
||||||
filename = @"SOGoAppointmentObjectAcceptOrDecline.toolbar";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
person = [persons nextObject];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return filename;
|
[component setAttendees: newAttendees];
|
||||||
|
[newAttendees release];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSString *) toolbar
|
- (void) takeValuesFromRequest: (WORequest *) _rq
|
||||||
|
inContext: (WOContext *) _ctx
|
||||||
{
|
{
|
||||||
NSString *filename;
|
NSCalendarDate *now;
|
||||||
iCalEntityObject *calObject;
|
|
||||||
SOGoCalendarComponent *co;
|
|
||||||
|
|
||||||
if (componentLoaded)
|
[super takeValuesFromRequest: _rq inContext: _ctx];
|
||||||
|
|
||||||
|
now = [NSCalendarDate calendarDate];
|
||||||
|
[component setSummary: title];
|
||||||
|
[component setLocation: location];
|
||||||
|
[component setComment: comment];
|
||||||
|
[component setUrl: url];
|
||||||
|
if ([[self clientObject] isNew])
|
||||||
{
|
{
|
||||||
co = [self clientObject];
|
[component setCreated: now];
|
||||||
calObject = [co component];
|
[component setTimeStampAsDate: now];
|
||||||
filename = [self _toolbarForCalObject: calObject];
|
[component setPriority: @"0"];
|
||||||
}
|
}
|
||||||
else
|
[component setLastModified: now];
|
||||||
filename = @"";
|
[self _handleAttendeesEdition];
|
||||||
|
|
||||||
return filename;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* UIxTaskEditor.h - this file is part of SOGo
|
/* UIxTaskEditor.h - this file is part of SOGo
|
||||||
*
|
*
|
||||||
* Copyright (C) 2006 Inverse groupe conseil
|
* Copyright (C) 2007 Inverse groupe conseil
|
||||||
*
|
*
|
||||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||||
*
|
*
|
||||||
|
@ -20,59 +20,41 @@
|
||||||
* Boston, MA 02111-1307, USA.
|
* Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef UIXTASKEDITOR_H
|
#ifndef UIXAPPOINTMENTEDITOR_H
|
||||||
#define UIXTASKEDITOR_H
|
#define UIXAPPOINTMENTEDITOR_H
|
||||||
|
|
||||||
#import "UIxComponentEditor.h"
|
#import <SOGoUI/UIxComponent.h>
|
||||||
|
|
||||||
@class NSString;
|
|
||||||
@class iCalPerson;
|
|
||||||
@class iCalRecurrenceRule;
|
|
||||||
@class iCalToDo;
|
@class iCalToDo;
|
||||||
|
@class NSString;
|
||||||
|
|
||||||
@interface UIxTaskEditor : UIxComponentEditor
|
@interface UIxTaskEditor : UIxComponent
|
||||||
{
|
{
|
||||||
NSCalendarDate *dueDate;
|
iCalToDo *todo;
|
||||||
|
NSCalendarDate *taskStartDate;
|
||||||
|
NSCalendarDate *taskDueDate;
|
||||||
|
NSCalendarDate *statusDate;
|
||||||
|
NSString *status;
|
||||||
|
NSString *statusPercent;
|
||||||
BOOL hasStartDate;
|
BOOL hasStartDate;
|
||||||
BOOL hasDueDate;
|
BOOL hasDueDate;
|
||||||
BOOL newTask;
|
NSString *item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* template values */
|
||||||
|
- (NSString *) saveURL;
|
||||||
|
- (iCalToDo *) todo;
|
||||||
|
|
||||||
|
/* icalendar values */
|
||||||
- (void) setTaskStartDate: (NSCalendarDate *) _date;
|
- (void) setTaskStartDate: (NSCalendarDate *) _date;
|
||||||
- (NSCalendarDate *) taskStartDate;
|
- (NSCalendarDate *) taskStartDate;
|
||||||
|
|
||||||
- (void) setTaskDueDate: (NSCalendarDate *) _date;
|
- (void) setTaskDueDate: (NSCalendarDate *) _date;
|
||||||
- (NSCalendarDate *) taskDueDate;
|
- (NSCalendarDate *) taskDueDate;
|
||||||
|
|
||||||
/* iCal */
|
- (NSString *) repeat;
|
||||||
|
- (void) setRepeat: (NSString *) newRepeat;
|
||||||
- (NSString *) iCalStringTemplate;
|
|
||||||
|
|
||||||
/* new */
|
|
||||||
|
|
||||||
- (id) newAction;
|
|
||||||
|
|
||||||
/* save */
|
|
||||||
|
|
||||||
- (void) loadValuesFromTask: (iCalToDo *) _task;
|
|
||||||
- (void) saveValuesIntoTask: (iCalToDo *) _task;
|
|
||||||
- (iCalToDo *) taskFromString: (NSString *) _iCalString;
|
|
||||||
|
|
||||||
/* conflict management */
|
|
||||||
|
|
||||||
- (BOOL) containsConflict: (id) _task;
|
|
||||||
- (id <WOActionResults>) defaultAction;
|
|
||||||
- (id <WOActionResults>) saveAction;
|
|
||||||
- (id) changeStatusAction;
|
|
||||||
- (id) acceptAction;
|
|
||||||
- (id) declineAction;
|
|
||||||
|
|
||||||
- (NSString *) saveUrl;
|
|
||||||
|
|
||||||
// TODO: add tentatively
|
|
||||||
|
|
||||||
- (id) acceptOrDeclineAction: (BOOL) _accept;
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
#endif /* UIXTASKEDITOR_H */
|
#endif /* UIXAPPOINTMENTEDITOR_H */
|
||||||
|
|
|
@ -1,503 +1,432 @@
|
||||||
/*
|
/* UIxTaskEditor.m - this file is part of SOGo
|
||||||
Copyright (C) 2004-2005 SKYRIX Software AG
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
This file is part of OpenGroupware.org.
|
#import <NGObjWeb/SoObject.h>
|
||||||
|
#import <NGObjWeb/WORequest.h>
|
||||||
|
#import <NGObjWeb/NSException+HTTP.h>
|
||||||
|
#import <NGExtensions/NSCalendarDate+misc.h>
|
||||||
|
|
||||||
OGo is free software; you can redistribute it and/or modify it under
|
#import <NGCards/iCalToDo.h>
|
||||||
the terms of the GNU Lesser General Public License as published by the
|
#import <NGCards/iCalPerson.h>
|
||||||
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
|
#import <SoObjects/SOGo/AgenorUserManager.h>
|
||||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
#import <SoObjects/SOGo/SOGoUser.h>
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
#import <SoObjects/SOGo/SOGoContentObject.h>
|
||||||
License for more details.
|
#import <SoObjects/Appointments/SOGoAppointmentFolder.h>
|
||||||
|
#import <SoObjects/Appointments/SOGoTaskObject.h>
|
||||||
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 <SOGo/NSCalendarDate+SOGo.h>
|
|
||||||
|
|
||||||
|
#import "UIxComponentEditor.h"
|
||||||
#import "UIxTaskEditor.h"
|
#import "UIxTaskEditor.h"
|
||||||
|
|
||||||
/* TODO: CLEAN UP */
|
|
||||||
|
|
||||||
#import "common.h"
|
|
||||||
#import <NGCards/NGCards.h>
|
|
||||||
#import <NGExtensions/NGCalendarDateRange.h>
|
|
||||||
#import <SOGoUI/SOGoDateFormatter.h>
|
|
||||||
#import <SOGo/AgenorUserManager.h>
|
|
||||||
#import <Appointments/SOGoAppointmentFolder.h>
|
|
||||||
#import <Appointments/SOGoTaskObject.h>
|
|
||||||
#import "UIxComponent+Agenor.h"
|
|
||||||
|
|
||||||
@implementation UIxTaskEditor
|
@implementation UIxTaskEditor
|
||||||
|
|
||||||
- (void) dealloc
|
- (id) init
|
||||||
{
|
{
|
||||||
[dueDate release];
|
if ((self = [super init]))
|
||||||
[super dealloc];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void) setTaskStartDate: (NSCalendarDate *) _date
|
|
||||||
{
|
|
||||||
[self setStartDate: _date];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSCalendarDate *) taskStartDate
|
|
||||||
{
|
|
||||||
return [self startDate];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void) setTaskDueDate: (NSCalendarDate *) _date
|
|
||||||
{
|
|
||||||
ASSIGN(dueDate, _date);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSCalendarDate *) taskDueDate
|
|
||||||
{
|
|
||||||
return dueDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* iCal */
|
|
||||||
|
|
||||||
- (NSString *) iCalStringTemplate
|
|
||||||
{
|
|
||||||
static NSString *iCalStringTemplate = \
|
|
||||||
@"BEGIN:VCALENDAR\r\n"
|
|
||||||
@"METHOD:REQUEST\r\n"
|
|
||||||
@"PRODID://Inverse groupe conseil/SOGo 0.9\r\n"
|
|
||||||
@"VERSION:2.0\r\n"
|
|
||||||
@"BEGIN:VTODO\r\n"
|
|
||||||
@"UID:%@\r\n"
|
|
||||||
@"CLASS:PUBLIC\r\n"
|
|
||||||
@"STATUS:NEEDS-ACTION\r\n" /* confirmed by default */
|
|
||||||
@"PERCENT-COMPLETE:0\r\n"
|
|
||||||
@"DTSTART:%@Z\r\n"
|
|
||||||
@"DUE:%@Z\r\n"
|
|
||||||
@"DTSTAMP:%@Z\r\n"
|
|
||||||
@"SEQUENCE:1\r\n"
|
|
||||||
@"PRIORITY:5\r\n"
|
|
||||||
@"%@" /* organizer */
|
|
||||||
@"%@" /* participants and resources */
|
|
||||||
@"END:VTODO\r\n"
|
|
||||||
@"END:VCALENDAR";
|
|
||||||
|
|
||||||
NSCalendarDate *stamp, *lStartDate, *lDueDate;
|
|
||||||
NSString *template, *s;
|
|
||||||
NSTimeZone *utc;
|
|
||||||
unsigned minutes;
|
|
||||||
|
|
||||||
s = [self queryParameterForKey:@"dur"];
|
|
||||||
if ([s length] > 0)
|
|
||||||
minutes = [s intValue];
|
|
||||||
else
|
|
||||||
minutes = 60;
|
|
||||||
|
|
||||||
utc = [NSTimeZone timeZoneWithName: @"GMT"];
|
|
||||||
lStartDate = [self newStartDate];
|
|
||||||
[lStartDate setTimeZone: utc];
|
|
||||||
lDueDate = [lStartDate dateByAddingYears: 0 months: 0 days: 0
|
|
||||||
hours: 0 minutes: minutes seconds: 0];
|
|
||||||
stamp = [NSCalendarDate calendarDate];
|
|
||||||
[stamp setTimeZone: utc];
|
|
||||||
|
|
||||||
s = [self iCalParticipantsAndResourcesStringFromQueryParameters];
|
|
||||||
template = [NSString stringWithFormat:iCalStringTemplate,
|
|
||||||
[[self clientObject] nameInContainer],
|
|
||||||
[lStartDate iCalFormattedDateTimeString],
|
|
||||||
[lDueDate iCalFormattedDateTimeString],
|
|
||||||
[stamp iCalFormattedDateTimeString],
|
|
||||||
[self iCalOrganizerString],
|
|
||||||
s];
|
|
||||||
return template;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* new */
|
|
||||||
|
|
||||||
- (id) newAction
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
This method creates a unique ID and redirects to the "edit" method on the
|
|
||||||
new ID.
|
|
||||||
It is actually a folder method and should be defined on the folder.
|
|
||||||
|
|
||||||
Note: 'clientObject' is the SOGoAppointmentFolder!
|
|
||||||
Update: remember that there are group folders as well.
|
|
||||||
*/
|
|
||||||
NSString *uri, *objectId, *method, *ps;
|
|
||||||
|
|
||||||
objectId = [NSClassFromString(@"SOGoAppointmentFolder")
|
|
||||||
globallyUniqueObjectId];
|
|
||||||
if ([objectId length] == 0) {
|
|
||||||
return [NSException exceptionWithHTTPStatus:500 /* Internal Error */
|
|
||||||
reason:@"could not create a unique ID"];
|
|
||||||
}
|
|
||||||
|
|
||||||
method = [NSString stringWithFormat:@"Calendar/%@/editAsTask", objectId];
|
|
||||||
method = [[self userFolderPath] stringByAppendingPathComponent:method];
|
|
||||||
|
|
||||||
/* check if participants have already been provided */
|
|
||||||
ps = [self queryParameterForKey:@"ps"];
|
|
||||||
// if (ps) {
|
|
||||||
// [self setQueryParameter:ps forKey:@"ps"];
|
|
||||||
// }
|
|
||||||
if (!ps
|
|
||||||
&& [[self clientObject] respondsToSelector:@selector(calendarUIDs)]) {
|
|
||||||
AgenorUserManager *um;
|
|
||||||
NSArray *uids;
|
|
||||||
NSMutableArray *emails;
|
|
||||||
unsigned i, count;
|
|
||||||
|
|
||||||
/* add all current calendarUIDs as default participants */
|
|
||||||
|
|
||||||
um = [AgenorUserManager sharedUserManager];
|
|
||||||
uids = [[self clientObject] calendarUIDs];
|
|
||||||
count = [uids count];
|
|
||||||
emails = [NSMutableArray arrayWithCapacity:count];
|
|
||||||
|
|
||||||
for (i = 0; i < count; i++) {
|
|
||||||
NSString *email;
|
|
||||||
|
|
||||||
email = [um getEmailForUID:[uids objectAtIndex:i]];
|
|
||||||
if (email)
|
|
||||||
[emails addObject:email];
|
|
||||||
}
|
|
||||||
ps = [emails componentsJoinedByString:@","];
|
|
||||||
[self setQueryParameter:ps forKey:@"ps"];
|
|
||||||
}
|
|
||||||
uri = [self completeHrefForMethod:method];
|
|
||||||
return [self redirectToLocation:uri];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* save */
|
|
||||||
|
|
||||||
- (void) loadValuesFromTask: (iCalToDo *) _task
|
|
||||||
{
|
|
||||||
NSTimeZone *uTZ;
|
|
||||||
|
|
||||||
[self loadValuesFromComponent: _task];
|
|
||||||
|
|
||||||
uTZ = [[self clientObject] userTimeZone];
|
|
||||||
dueDate = [_task due];
|
|
||||||
// if (!dueDate)
|
|
||||||
// dueDate = [[self startDate] dateByAddingYears: 0 months: 0 days: 0
|
|
||||||
// hours: 1 minutes: 0 seconds: 0];
|
|
||||||
if (dueDate)
|
|
||||||
{
|
{
|
||||||
[dueDate setTimeZone: uTZ];
|
taskStartDate = nil;
|
||||||
[dueDate retain];
|
taskDueDate = nil;
|
||||||
|
statusDate = nil;
|
||||||
|
hasStartDate = NO;
|
||||||
|
hasDueDate = NO;
|
||||||
|
status = nil;
|
||||||
|
statusPercent = nil;
|
||||||
|
item = nil;
|
||||||
|
todo = nil;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
- (void) saveValuesIntoTask: (iCalToDo *) _task
|
|
||||||
{
|
|
||||||
/* merge in form values */
|
|
||||||
NSArray *attendees, *lResources;
|
|
||||||
iCalRecurrenceRule *rrule;
|
|
||||||
NSCalendarDate *dateTime;
|
|
||||||
|
|
||||||
if (hasStartDate)
|
|
||||||
dateTime = [self taskStartDate];
|
|
||||||
else
|
|
||||||
dateTime = nil;
|
|
||||||
[_task setStartDate: dateTime];
|
|
||||||
if (hasDueDate)
|
|
||||||
dateTime = [self taskDueDate];
|
|
||||||
else
|
|
||||||
dateTime = nil;
|
|
||||||
[_task setDue: dateTime];
|
|
||||||
|
|
||||||
[_task setSummary: [self title]];
|
|
||||||
[_task setUrl: [self url]];
|
|
||||||
[_task setLocation: [self location]];
|
|
||||||
[_task setComment: [self comment]];
|
|
||||||
[_task setPriority:[self priority]];
|
|
||||||
[_task setAccessClass: [self privacy]];
|
|
||||||
[_task setStatus: [self status]];
|
|
||||||
|
|
||||||
// [_task setCategories: [[self categories] componentsJoinedByString: @","]];
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
/*
|
|
||||||
Note: bad, bad, bad!
|
|
||||||
Organizer is no form value, thus we MUST NOT change it
|
|
||||||
*/
|
|
||||||
[_task setOrganizer:organizer];
|
|
||||||
#endif
|
|
||||||
attendees = [self participants];
|
|
||||||
lResources = [self resources];
|
|
||||||
if ([lResources count] > 0) {
|
|
||||||
attendees = ([attendees count] > 0)
|
|
||||||
? [attendees arrayByAddingObjectsFromArray:lResources]
|
|
||||||
: lResources;
|
|
||||||
}
|
|
||||||
[attendees makeObjectsPerformSelector: @selector (setTag:)
|
|
||||||
withObject: @"attendee"];
|
|
||||||
[_task setAttendees:attendees];
|
|
||||||
|
|
||||||
/* cycles */
|
|
||||||
[_task removeAllRecurrenceRules];
|
|
||||||
rrule = [self rrule];
|
|
||||||
if (rrule)
|
|
||||||
[_task addToRecurrenceRules: rrule];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (iCalToDo *) taskFromString: (NSString *) _iCalString
|
|
||||||
{
|
|
||||||
iCalCalendar *calendar;
|
|
||||||
iCalToDo *task;
|
|
||||||
|
|
||||||
calendar = [iCalCalendar parseSingleFromSource: _iCalString];
|
|
||||||
task = (iCalToDo *) [calendar firstChildWithTag: @"vtodo"];
|
|
||||||
|
|
||||||
return task;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* conflict management */
|
|
||||||
|
|
||||||
- (BOOL) containsConflict: (id) _task
|
|
||||||
{
|
|
||||||
NSArray *attendees, *uids;
|
|
||||||
SOGoAppointmentFolder *groupCalendar;
|
|
||||||
NSArray *infos;
|
|
||||||
NSArray *ranges;
|
|
||||||
id folder;
|
|
||||||
|
|
||||||
[self logWithFormat:@"search from %@ to %@",
|
|
||||||
[_task startDate], [_task due]];
|
|
||||||
|
|
||||||
folder = [[self clientObject] container];
|
|
||||||
attendees = [_task attendees];
|
|
||||||
uids = [folder uidsFromICalPersons:attendees];
|
|
||||||
if ([uids count] == 0) {
|
|
||||||
[self logWithFormat:@"Note: no UIDs selected."];
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
groupCalendar = [folder lookupGroupCalendarFolderForUIDs:uids
|
|
||||||
inContext:[self context]];
|
|
||||||
[self debugWithFormat:@"group calendar: %@", groupCalendar];
|
|
||||||
|
|
||||||
if (![groupCalendar respondsToSelector:@selector(fetchFreeBusyInfosFrom:to:)]) {
|
|
||||||
[self errorWithFormat:@"invalid folder to run freebusy query on!"];
|
|
||||||
return NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
infos = [groupCalendar fetchFreeBusyInfosFrom:[_task startDate]
|
|
||||||
to:[_task due]];
|
|
||||||
[self debugWithFormat:@" process: %d tasks", [infos count]];
|
|
||||||
|
|
||||||
ranges = [infos arrayByCreatingDateRangesFromObjectsWithStartDateKey:@"startDate"
|
|
||||||
andEndDateKey:@"dueDate"];
|
|
||||||
ranges = [ranges arrayByCompactingContainedDateRanges];
|
|
||||||
[self debugWithFormat:@" blocked ranges: %@", ranges];
|
|
||||||
|
|
||||||
return [ranges count] != 0 ? YES : NO;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id <WOActionResults>) defaultAction
|
|
||||||
{
|
|
||||||
NSString *ical;
|
|
||||||
|
|
||||||
/* load iCalendar file */
|
|
||||||
|
|
||||||
// TODO: can't we use [clientObject contentAsString]?
|
|
||||||
// ical = [[self clientObject] valueForKey:@"iCalString"];
|
|
||||||
ical = [[self clientObject] contentAsString];
|
|
||||||
if ([ical length] == 0)
|
|
||||||
{
|
|
||||||
newTask = YES;
|
|
||||||
ical = [self iCalStringTemplate];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
newTask = NO;
|
|
||||||
|
|
||||||
[self setICalString:ical];
|
|
||||||
[self loadValuesFromTask: [self taskFromString: ical]];
|
|
||||||
|
|
||||||
// if (![self canEditComponent]) {
|
|
||||||
// /* TODO: we need proper ACLs */
|
|
||||||
// return [self redirectToLocation: [self completeURIForMethod: @"../view"]];
|
|
||||||
// }
|
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id <WOActionResults>) saveAction
|
- (void) dealloc
|
||||||
{
|
{
|
||||||
iCalToDo *task;
|
[taskStartDate release];
|
||||||
iCalPerson *p;
|
[taskDueDate release];
|
||||||
id <WOActionResults> result;
|
[statusDate release];
|
||||||
NSString *content;
|
[status release];
|
||||||
NSException *ex;
|
[statusPercent release];
|
||||||
|
[super dealloc];
|
||||||
if (![self isWriteableClientObject]) {
|
|
||||||
/* return 400 == Bad Request */
|
|
||||||
return [NSException exceptionWithHTTPStatus:400
|
|
||||||
reason: @"method cannot be invoked on "
|
|
||||||
@"the specified object"];
|
|
||||||
}
|
|
||||||
|
|
||||||
task = [self taskFromString: [self iCalString]];
|
|
||||||
if (task == nil) {
|
|
||||||
NSString *s;
|
|
||||||
|
|
||||||
s = [self labelForKey: @"Invalid iCal data!"];
|
|
||||||
[self setErrorText: s];
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
[self saveValuesIntoTask:task];
|
|
||||||
p = [task findParticipantWithEmail:[self emailForUser]];
|
|
||||||
if (p) {
|
|
||||||
[p setParticipationStatus:iCalPersonPartStatAccepted];
|
|
||||||
}
|
|
||||||
|
|
||||||
if ([self checkForConflicts]) {
|
|
||||||
if ([self containsConflict:task]) {
|
|
||||||
NSString *s;
|
|
||||||
|
|
||||||
s = [self labelForKey:@"Conflicts found!"];
|
|
||||||
[self setErrorText:s];
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
content = [[task parent] versitString];
|
|
||||||
// [task release]; task = nil;
|
|
||||||
|
|
||||||
if (content == nil) {
|
|
||||||
NSString *s;
|
|
||||||
|
|
||||||
s = [self labelForKey: @"Could not create iCal data!"];
|
|
||||||
[self setErrorText: s];
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
ex = [[self clientObject] saveContentString:content];
|
|
||||||
if (ex != nil) {
|
|
||||||
[self setErrorText:[ex reason]];
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ([[[[self context] request] formValueForKey: @"nojs"] intValue])
|
|
||||||
result = [self redirectToLocation: [self applicationPath]];
|
|
||||||
else
|
|
||||||
result = [self jsCloseWithRefreshMethod: @"refreshTasks()"];
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id) changeStatusAction
|
/* template values */
|
||||||
|
- (iCalToDo *) todo
|
||||||
{
|
{
|
||||||
iCalToDo *task;
|
return todo;
|
||||||
SOGoTaskObject *taskObject;
|
|
||||||
NSString *content;
|
|
||||||
id ex;
|
|
||||||
int newStatus;
|
|
||||||
|
|
||||||
newStatus = [[self queryParameterForKey: @"status"] intValue];
|
|
||||||
|
|
||||||
taskObject = [self clientObject];
|
|
||||||
task = (iCalToDo *) [taskObject component];
|
|
||||||
switch (newStatus)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
[task setCompleted: [NSCalendarDate calendarDate]];
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
[task setStatus: @"IN-PROCESS"];
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
[task setStatus: @"CANCELLED"];
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
[task setStatus: @"NEEDS-ACTION"];
|
|
||||||
}
|
|
||||||
|
|
||||||
content = [[task parent] versitString];
|
|
||||||
ex = [[self clientObject] saveContentString: content];
|
|
||||||
if (ex != nil) {
|
|
||||||
[self setErrorText:[ex reason]];
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
return [self redirectToLocation: [self completeURIForMethod: @".."]];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id)acceptAction {
|
- (NSString *) saveURL
|
||||||
return [self acceptOrDeclineAction:YES];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)declineAction {
|
|
||||||
return [self acceptOrDeclineAction:NO];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSString *) saveUrl
|
|
||||||
{
|
{
|
||||||
return [NSString stringWithFormat: @"%@/saveAsTask",
|
return [NSString stringWithFormat: @"%@/saveAsTask",
|
||||||
[[self clientObject] baseURL]];
|
[[self clientObject] baseURL]];
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: add tentatively
|
- (NSString *) _toolbarForCalObject
|
||||||
|
{
|
||||||
|
SOGoUser *currentUser;
|
||||||
|
SOGoTaskObject *clientObject;
|
||||||
|
NSString *filename, *email;
|
||||||
|
iCalPerson *person;
|
||||||
|
iCalPersonPartStat participationStatus;
|
||||||
|
|
||||||
- (id)acceptOrDeclineAction:(BOOL)_accept {
|
clientObject = [self clientObject];
|
||||||
// TODO: this should live in the SoObjects
|
currentUser = [[self context] activeUser];
|
||||||
NSException *ex;
|
email = [currentUser email];
|
||||||
|
if ([clientObject isOrganizer: email
|
||||||
|
orOwner: [currentUser login]])
|
||||||
|
filename = @"SOGoTaskObject.toolbar";
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ([clientObject isParticipant: email])
|
||||||
|
{
|
||||||
|
person = [[clientObject component: NO] findParticipantWithEmail: email];
|
||||||
|
participationStatus = [person participationStatus];
|
||||||
|
if (participationStatus == iCalPersonPartStatAccepted)
|
||||||
|
filename = @"SOGoTaskObjectDecline.toolbar";
|
||||||
|
else if (participationStatus == iCalPersonPartStatDeclined)
|
||||||
|
filename = @"SOGoTaskObjectAccept.toolbar";
|
||||||
|
else
|
||||||
|
filename = @"SOGoTaskObjectAcceptOrDecline.toolbar";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
filename = @"";
|
||||||
|
}
|
||||||
|
|
||||||
if ((ex = [self validateObjectForStatusChange]) != nil)
|
return filename;
|
||||||
return ex;
|
|
||||||
|
|
||||||
ex = [[self clientObject] changeParticipationStatus:
|
|
||||||
_accept ? @"ACCEPTED" : @"DECLINED"
|
|
||||||
inContext:[self context]];
|
|
||||||
if (ex != nil) return ex;
|
|
||||||
|
|
||||||
return self;
|
|
||||||
// return [self redirectToLocation: [self completeURIForMethod:@"../view"]];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) setHasStartDate: (BOOL) aBool
|
- (NSString *) toolbar
|
||||||
{
|
{
|
||||||
hasStartDate = aBool;
|
return ([self _toolbarForCalObject]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* icalendar values */
|
||||||
|
- (void) setTaskStartDate: (NSCalendarDate *) newTaskStartDate
|
||||||
|
{
|
||||||
|
ASSIGN (taskStartDate, newTaskStartDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSCalendarDate *) taskStartDate
|
||||||
|
{
|
||||||
|
return taskStartDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) setHasStartDate: (BOOL) newHasStartDate
|
||||||
|
{
|
||||||
|
hasStartDate = newHasStartDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL) hasStartDate
|
- (BOOL) hasStartDate
|
||||||
{
|
{
|
||||||
return (!newTask && [self taskStartDate] != nil);
|
return hasStartDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL) startDateDisabled
|
- (BOOL) startDateDisabled
|
||||||
{
|
{
|
||||||
return (![self hasStartDate]);
|
return !hasStartDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) setHasDueDate: (BOOL) aBool
|
- (void) setTaskDueDate: (NSCalendarDate *) newTaskDueDate
|
||||||
{
|
{
|
||||||
hasDueDate = aBool;
|
ASSIGN (taskDueDate, newTaskDueDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSCalendarDate *) taskDueDate
|
||||||
|
{
|
||||||
|
return taskDueDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) setHasDueDate: (BOOL) newHasDueDate
|
||||||
|
{
|
||||||
|
hasDueDate = newHasDueDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL) hasDueDate
|
- (BOOL) hasDueDate
|
||||||
{
|
{
|
||||||
return (!newTask && [self taskDueDate] != nil);
|
return hasDueDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL) dueDateDisabled
|
- (BOOL) dueDateDisabled
|
||||||
{
|
{
|
||||||
return (![self hasDueDate]);
|
return !hasDueDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) setDueDateDisabled: (BOOL) aBool
|
- (NSArray *) repeatList
|
||||||
|
{
|
||||||
|
static NSArray *repeatItems = nil;
|
||||||
|
|
||||||
|
if (!repeatItems)
|
||||||
|
{
|
||||||
|
repeatItems = [NSArray arrayWithObjects: @"DAILY",
|
||||||
|
@"WEEKLY",
|
||||||
|
@"BI-WEEKLY",
|
||||||
|
@"EVERY WEEKDAY",
|
||||||
|
@"MONTHLY",
|
||||||
|
@"YEARLY",
|
||||||
|
@"-",
|
||||||
|
@"CUSTOM",
|
||||||
|
nil];
|
||||||
|
[repeatItems retain];
|
||||||
|
}
|
||||||
|
|
||||||
|
return repeatItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *) itemRepeatText
|
||||||
|
{
|
||||||
|
NSString *text;
|
||||||
|
|
||||||
|
if ([item isEqualToString: @"-"])
|
||||||
|
text = item;
|
||||||
|
else
|
||||||
|
text = [self labelForKey: [NSString stringWithFormat: @"repeat_%@", item]];
|
||||||
|
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSArray *) statusList
|
||||||
|
{
|
||||||
|
static NSArray *statusItems = nil;
|
||||||
|
|
||||||
|
if (!statusItems)
|
||||||
|
{
|
||||||
|
statusItems = [NSArray arrayWithObjects: @"NEEDS-ACTION",
|
||||||
|
@"IN-PROCESS",
|
||||||
|
@"COMPLETED",
|
||||||
|
@"CANCELLED",
|
||||||
|
nil];
|
||||||
|
[statusItems retain];
|
||||||
|
}
|
||||||
|
|
||||||
|
return statusItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *) itemStatusText
|
||||||
|
{
|
||||||
|
return [self labelForKey: [NSString stringWithFormat: @"status_%@", item]];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) setItem: (NSString *) newItem
|
||||||
|
{
|
||||||
|
item = newItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *) item
|
||||||
|
{
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *) repeat
|
||||||
|
{
|
||||||
|
return @"";
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) setRepeat: (NSString *) newRepeat
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) setStartDateDisabled: (BOOL) aBool
|
- (NSString *) status
|
||||||
{
|
{
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@end /* UIxTaskEditor */
|
- (void) setStatus: (NSString *) newStatus
|
||||||
|
{
|
||||||
|
status = newStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) setStatusDate: (NSCalendarDate *) newStatusDate
|
||||||
|
{
|
||||||
|
ASSIGN (statusDate, newStatusDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSCalendarDate *) statusDate
|
||||||
|
{
|
||||||
|
return statusDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL) statusDateDisabled
|
||||||
|
{
|
||||||
|
return ![status isEqualToString: @"COMPLETED"];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL) statusPercentDisabled
|
||||||
|
{
|
||||||
|
NSLog (@"status: '%@'", status);
|
||||||
|
return ([status length] == 0
|
||||||
|
|| [status isEqualToString: @"CANCELLED"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) setStatusPercent: (NSString *) newStatusPercent
|
||||||
|
{
|
||||||
|
ASSIGN (statusPercent, newStatusPercent);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSString *) statusPercent
|
||||||
|
{
|
||||||
|
return statusPercent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* actions */
|
||||||
|
- (NSCalendarDate *) newStartDate
|
||||||
|
{
|
||||||
|
NSCalendarDate *newStartDate, *now;
|
||||||
|
int hour;
|
||||||
|
|
||||||
|
newStartDate = [self selectedDate];
|
||||||
|
if ([[self queryParameterForKey: @"hm"] length] == 0)
|
||||||
|
{
|
||||||
|
now = [NSCalendarDate calendarDate];
|
||||||
|
[now setTimeZone: [[self clientObject] userTimeZone]];
|
||||||
|
if ([now isDateOnSameDay: newStartDate])
|
||||||
|
{
|
||||||
|
hour = [now hourOfDay];
|
||||||
|
if (hour < 8)
|
||||||
|
newStartDate = [now hour: 8 minute: 0];
|
||||||
|
else if (hour > 18)
|
||||||
|
newStartDate = [[now tomorrow] hour: 8 minute: 0];
|
||||||
|
else
|
||||||
|
newStartDate = now;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
newStartDate = [newStartDate hour: 8 minute: 0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return newStartDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id <WOActionResults>) defaultAction
|
||||||
|
{
|
||||||
|
NSCalendarDate *startDate, *dueDate;
|
||||||
|
NSString *duration;
|
||||||
|
unsigned int minutes;
|
||||||
|
|
||||||
|
todo = (iCalToDo *) [[self clientObject] component: NO];
|
||||||
|
if (todo)
|
||||||
|
{
|
||||||
|
startDate = [todo startDate];
|
||||||
|
dueDate = [todo due];
|
||||||
|
hasStartDate = (startDate != nil);
|
||||||
|
hasDueDate = (dueDate != nil);
|
||||||
|
ASSIGN (status, [todo status]);
|
||||||
|
if ([status isEqualToString: @"COMPLETED"])
|
||||||
|
ASSIGN (statusDate, [todo completed]);
|
||||||
|
else
|
||||||
|
ASSIGN (statusDate, [self newStartDate]);
|
||||||
|
ASSIGN (statusPercent, [todo percentComplete]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
startDate = [self newStartDate];
|
||||||
|
duration = [self queryParameterForKey:@"dur"];
|
||||||
|
if ([duration length] > 0)
|
||||||
|
minutes = [duration intValue];
|
||||||
|
else
|
||||||
|
minutes = 60;
|
||||||
|
dueDate = [startDate dateByAddingYears: 0 months: 0 days: 0
|
||||||
|
hours: 0 minutes: minutes seconds: 0];
|
||||||
|
hasStartDate = NO;
|
||||||
|
hasDueDate = NO;
|
||||||
|
ASSIGN (statusDate, [self newStartDate]);
|
||||||
|
ASSIGN (status, @"");
|
||||||
|
ASSIGN (statusPercent, @"");
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSIGN (taskStartDate, startDate);
|
||||||
|
ASSIGN (taskDueDate, dueDate);
|
||||||
|
|
||||||
|
/* here comes the code for initializing repeat, reminder and isAllDay... */
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id <WOActionResults>) newAction
|
||||||
|
{
|
||||||
|
NSString *objectId, *method, *uri;
|
||||||
|
id <WOActionResults> result;
|
||||||
|
Class clientKlazz;
|
||||||
|
|
||||||
|
clientKlazz = [[self clientObject] class];
|
||||||
|
objectId = [clientKlazz globallyUniqueObjectId];
|
||||||
|
if ([objectId length] > 0)
|
||||||
|
{
|
||||||
|
method = [NSString stringWithFormat:@"%@/Calendar/%@/editAsTask",
|
||||||
|
[self userFolderPath], objectId];
|
||||||
|
uri = [self completeHrefForMethod: method];
|
||||||
|
result = [self redirectToLocation: uri];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
result = [NSException exceptionWithHTTPStatus: 500 /* Internal Error */
|
||||||
|
reason: @"could not create a unique ID"];
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id <WOActionResults>) saveAction
|
||||||
|
{
|
||||||
|
SOGoTaskObject *clientObject;
|
||||||
|
NSString *iCalString;
|
||||||
|
|
||||||
|
clientObject = [self clientObject];
|
||||||
|
iCalString = [[clientObject calendar: NO] versitString];
|
||||||
|
[clientObject saveContentString: iCalString];
|
||||||
|
|
||||||
|
return [self jsCloseWithRefreshMethod: @"refreshTasks()"];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL) shouldTakeValuesFromRequest: (WORequest *) request
|
||||||
|
inContext: (WOContext*) context
|
||||||
|
{
|
||||||
|
return ([[self clientObject] isKindOfClass: [SOGoTaskObject class]]
|
||||||
|
&& [[request method] isEqualToString: @"POST"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) takeValuesFromRequest: (WORequest *) _rq
|
||||||
|
inContext: (WOContext *) _ctx
|
||||||
|
{
|
||||||
|
SOGoTaskObject *clientObject;
|
||||||
|
|
||||||
|
clientObject = [self clientObject];
|
||||||
|
todo = (iCalToDo *) [clientObject component: YES];
|
||||||
|
|
||||||
|
[super takeValuesFromRequest: _rq inContext: _ctx];
|
||||||
|
|
||||||
|
if (hasStartDate)
|
||||||
|
[todo setStartDate: taskStartDate];
|
||||||
|
if (hasDueDate)
|
||||||
|
[todo setDue: taskDueDate];
|
||||||
|
if ([status isEqualToString: @"COMPLETED"])
|
||||||
|
[todo setCompleted: statusDate];
|
||||||
|
else
|
||||||
|
[todo setCompleted: nil];
|
||||||
|
if ([status length] > 0)
|
||||||
|
{
|
||||||
|
[todo setStatus: status];
|
||||||
|
[todo setPercentComplete: statusPercent];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
[todo setStatus: @""];
|
||||||
|
[todo setPercentComplete: @""];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
Loading…
Reference in New Issue