2006-10-18 16:42:44 +02:00
|
|
|
/* UIxComponentEditor.m - this file is part of SOGo
|
|
|
|
*
|
|
|
|
* Copyright (C) 2006 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.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#import <Foundation/NSArray.h>
|
|
|
|
#import <Foundation/NSBundle.h>
|
|
|
|
#import <Foundation/NSException.h>
|
|
|
|
#import <Foundation/NSCalendarDate.h>
|
2007-04-11 21:38:06 +02:00
|
|
|
#import <Foundation/NSKeyValueCoding.h>
|
2006-10-18 16:42:44 +02:00
|
|
|
#import <Foundation/NSString.h>
|
2006-10-19 16:35:50 +02:00
|
|
|
#import <Foundation/NSUserDefaults.h>
|
2006-10-23 23:34:56 +02:00
|
|
|
#import <Foundation/NSURL.h>
|
2006-10-18 16:42:44 +02:00
|
|
|
|
|
|
|
#import <NGCards/iCalPerson.h>
|
|
|
|
#import <NGCards/iCalRepeatableEntityObject.h>
|
|
|
|
#import <NGCards/iCalRecurrenceRule.h>
|
|
|
|
#import <NGCards/NSString+NGCards.h>
|
|
|
|
#import <NGCards/NSCalendarDate+NGCards.h>
|
2007-06-01 23:01:44 +02:00
|
|
|
#import <NGObjWeb/SoSecurityManager.h>
|
|
|
|
#import <NGObjWeb/NSException+HTTP.h>
|
|
|
|
#import <NGObjWeb/WORequest.h>
|
2006-10-18 16:42:44 +02:00
|
|
|
#import <NGExtensions/NSCalendarDate+misc.h>
|
|
|
|
#import <NGExtensions/NSObject+Logs.h>
|
|
|
|
#import <NGExtensions/NSString+misc.h>
|
|
|
|
|
2007-04-02 21:27:46 +02:00
|
|
|
#import <SoObjects/Appointments/SOGoAppointmentFolder.h>
|
2006-11-07 19:15:29 +01:00
|
|
|
#import <SoObjects/Appointments/SOGoAppointmentObject.h>
|
|
|
|
#import <SoObjects/Appointments/SOGoTaskObject.h>
|
2007-04-11 21:34:24 +02:00
|
|
|
#import <SoObjects/SOGo/NSString+Utilities.h>
|
2007-06-01 23:01:44 +02:00
|
|
|
#import <SoObjects/SOGo/SOGoUser.h>
|
|
|
|
#import <SoObjects/SOGo/SOGoPermissions.h>
|
2006-10-18 16:42:44 +02:00
|
|
|
|
2007-05-09 21:23:45 +02:00
|
|
|
#import "UIxComponent+Scheduler.h"
|
2006-10-18 16:42:44 +02:00
|
|
|
|
|
|
|
#import "UIxComponentEditor.h"
|
|
|
|
|
|
|
|
@implementation UIxComponentEditor
|
|
|
|
|
|
|
|
- (id) init
|
|
|
|
{
|
|
|
|
if ((self = [super init]))
|
|
|
|
{
|
2007-03-18 16:20:38 +01:00
|
|
|
component = nil;
|
2006-11-03 20:38:08 +01:00
|
|
|
[self setPrivacy: @"PUBLIC"];
|
2006-10-18 16:42:44 +02:00
|
|
|
[self setIsCycleEndNever];
|
2006-10-19 16:35:50 +02:00
|
|
|
componentOwner = @"";
|
2007-03-19 00:52:08 +01:00
|
|
|
organizer = nil;
|
2007-03-18 16:20:38 +01:00
|
|
|
attendeesNames = nil;
|
|
|
|
attendeesEmails = nil;
|
2007-04-02 21:27:46 +02:00
|
|
|
calendarList = nil;
|
2006-10-18 16:42:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) dealloc
|
|
|
|
{
|
|
|
|
[item release];
|
|
|
|
[cycleUntilDate release];
|
|
|
|
[title release];
|
|
|
|
[location release];
|
|
|
|
[organizer release];
|
|
|
|
[comment release];
|
|
|
|
[priority release];
|
|
|
|
[categories release];
|
|
|
|
[cycle release];
|
|
|
|
[cycleEnd release];
|
2006-10-23 23:34:56 +02:00
|
|
|
[url release];
|
2007-03-18 16:20:38 +01:00
|
|
|
[attendeesNames release];
|
|
|
|
[attendeesEmails release];
|
2007-04-02 21:27:46 +02:00
|
|
|
[calendarList release];
|
2006-10-18 16:42:44 +02:00
|
|
|
|
|
|
|
[super dealloc];
|
|
|
|
}
|
|
|
|
|
2007-03-18 16:20:38 +01:00
|
|
|
- (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;
|
|
|
|
}
|
|
|
|
|
2006-10-18 16:42:44 +02:00
|
|
|
/* accessors */
|
|
|
|
|
|
|
|
- (void) setItem: (id) _item
|
|
|
|
{
|
2007-03-18 16:20:38 +01:00
|
|
|
ASSIGN (item, _item);
|
2006-10-18 16:42:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
- (id) item
|
|
|
|
{
|
|
|
|
return item;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *) itemPriorityText
|
|
|
|
{
|
|
|
|
return [self labelForKey: [NSString stringWithFormat: @"prio_%@", item]];
|
|
|
|
}
|
|
|
|
|
2006-11-03 20:38:08 +01:00
|
|
|
- (NSString *) itemPrivacyText
|
|
|
|
{
|
2007-04-27 21:41:04 +02:00
|
|
|
NSString *tag;
|
|
|
|
|
|
|
|
tag = [[self clientObject] componentTag];
|
|
|
|
|
|
|
|
return [self labelForKey: [NSString stringWithFormat: @"%@_%@", item, tag]];
|
2006-11-03 20:38:08 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *) itemStatusText
|
|
|
|
{
|
|
|
|
return [self labelForKey: [NSString stringWithFormat: @"status_%@", item]];
|
|
|
|
}
|
|
|
|
|
2007-03-18 16:20:38 +01:00
|
|
|
- (void) setTitle: (NSString *) _value
|
2006-10-18 16:42:44 +02:00
|
|
|
{
|
2007-03-18 16:20:38 +01:00
|
|
|
ASSIGN (title, _value);
|
2006-10-18 16:42:44 +02:00
|
|
|
}
|
|
|
|
|
2007-03-18 16:20:38 +01:00
|
|
|
- (NSString *) title
|
2006-10-18 16:42:44 +02:00
|
|
|
{
|
2007-03-18 16:20:38 +01:00
|
|
|
return title;
|
2006-10-18 16:42:44 +02:00
|
|
|
}
|
|
|
|
|
2007-03-18 16:20:38 +01:00
|
|
|
- (void) setUrl: (NSString *) _url
|
2006-10-18 16:42:44 +02:00
|
|
|
{
|
2007-03-18 16:20:38 +01:00
|
|
|
ASSIGN (url, _url);
|
2006-10-18 16:42:44 +02:00
|
|
|
}
|
|
|
|
|
2007-03-18 16:20:38 +01:00
|
|
|
- (NSString *) url
|
2006-10-18 16:42:44 +02:00
|
|
|
{
|
2007-03-18 16:20:38 +01:00
|
|
|
return url;
|
2006-10-18 16:42:44 +02:00
|
|
|
}
|
|
|
|
|
2007-03-18 16:20:38 +01:00
|
|
|
- (void) setAttendeesNames: (NSString *) newAttendeesNames
|
2006-10-18 16:42:44 +02:00
|
|
|
{
|
2007-03-18 16:20:38 +01:00
|
|
|
ASSIGN (attendeesNames, newAttendeesNames);
|
2006-10-18 16:42:44 +02:00
|
|
|
}
|
|
|
|
|
2007-03-18 16:20:38 +01:00
|
|
|
- (NSString *) attendeesNames
|
2006-10-18 16:42:44 +02:00
|
|
|
{
|
2007-03-18 16:20:38 +01:00
|
|
|
return attendeesNames;
|
2006-10-18 16:42:44 +02:00
|
|
|
}
|
|
|
|
|
2007-03-18 16:20:38 +01:00
|
|
|
- (void) setAttendeesEmails: (NSString *) newAttendeesEmails
|
2006-10-23 23:34:56 +02:00
|
|
|
{
|
2007-03-18 16:20:38 +01:00
|
|
|
ASSIGN (attendeesEmails, newAttendeesEmails);
|
2006-10-23 23:34:56 +02:00
|
|
|
}
|
|
|
|
|
2007-03-18 16:20:38 +01:00
|
|
|
- (NSString *) attendeesEmails
|
2006-10-23 23:34:56 +02:00
|
|
|
{
|
2007-03-18 16:20:38 +01:00
|
|
|
return attendeesEmails;
|
2006-10-23 23:34:56 +02:00
|
|
|
}
|
|
|
|
|
2006-10-18 16:42:44 +02:00
|
|
|
- (void) setLocation: (NSString *) _value
|
|
|
|
{
|
2007-03-18 16:20:38 +01:00
|
|
|
ASSIGN (location, _value);
|
2006-10-18 16:42:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *) location
|
|
|
|
{
|
|
|
|
return location;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) setComment: (NSString *) _value
|
|
|
|
{
|
2007-03-18 16:20:38 +01:00
|
|
|
ASSIGN (comment, _value);
|
2006-10-18 16:42:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *) comment
|
|
|
|
{
|
|
|
|
return comment;
|
|
|
|
}
|
|
|
|
|
2007-03-18 16:20:38 +01:00
|
|
|
- (NSArray *) categoryList
|
2006-10-18 16:42:44 +02:00
|
|
|
{
|
|
|
|
static NSArray *categoryItems = nil;
|
2007-03-18 16:20:38 +01:00
|
|
|
|
2006-10-18 16:42:44 +02:00
|
|
|
if (!categoryItems)
|
|
|
|
{
|
2007-03-18 16:20:38 +01:00
|
|
|
categoryItems = [NSArray arrayWithObjects: @"ANNIVERSARY",
|
|
|
|
@"BIRTHDAY",
|
|
|
|
@"BUSINESS",
|
|
|
|
@"CALLS",
|
|
|
|
@"CLIENTS",
|
|
|
|
@"COMPETITION",
|
|
|
|
@"CUSTOMER",
|
|
|
|
@"FAVORITES",
|
|
|
|
@"FOLLOW UP",
|
|
|
|
@"GIFTS",
|
|
|
|
@"HOLIDAYS",
|
|
|
|
@"IDEAS",
|
|
|
|
@"ISSUES",
|
|
|
|
@"MISCELLANEOUS",
|
|
|
|
@"PERSONAL",
|
|
|
|
@"PROJECTS",
|
|
|
|
@"PUBLIC HOLIDAY",
|
|
|
|
@"STATUS",
|
|
|
|
@"SUPPLIERS",
|
|
|
|
@"TRAVEL",
|
|
|
|
@"VACATION",
|
|
|
|
nil];
|
2006-10-18 16:42:44 +02:00
|
|
|
[categoryItems retain];
|
|
|
|
}
|
|
|
|
|
|
|
|
return categoryItems;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) setCategories: (NSArray *) _categories
|
|
|
|
{
|
2007-03-18 16:20:38 +01:00
|
|
|
ASSIGN (categories, _categories);
|
2006-10-18 16:42:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
- (NSArray *) categories
|
|
|
|
{
|
|
|
|
return categories;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *) itemCategoryText
|
|
|
|
{
|
2007-04-02 21:27:46 +02:00
|
|
|
return [self labelForKey:
|
|
|
|
[NSString stringWithFormat: @"category_%@", item]];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSArray *) calendarList
|
|
|
|
{
|
|
|
|
SOGoAppointmentFolder *folder;
|
|
|
|
NSEnumerator *allCalendars;
|
|
|
|
NSDictionary *currentCalendar;
|
|
|
|
|
|
|
|
if (!calendarList)
|
|
|
|
{
|
|
|
|
calendarList = [NSMutableArray new];
|
|
|
|
folder = [[self clientObject] container];
|
2007-04-11 21:08:58 +02:00
|
|
|
allCalendars = [[folder calendarFolders] objectEnumerator];
|
2007-04-02 21:27:46 +02:00
|
|
|
currentCalendar = [allCalendars nextObject];
|
|
|
|
while (currentCalendar)
|
|
|
|
{
|
|
|
|
if ([[currentCalendar objectForKey: @"active"] boolValue])
|
|
|
|
[calendarList addObject: currentCalendar];
|
|
|
|
currentCalendar = [allCalendars nextObject];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return calendarList;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *) calendarsFoldersList
|
|
|
|
{
|
|
|
|
NSArray *calendars;
|
|
|
|
|
|
|
|
calendars = [[self calendarList] valueForKey: @"folder"];
|
|
|
|
|
|
|
|
return [calendars componentsJoinedByString: @","];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *) componentCalendar
|
|
|
|
{
|
|
|
|
return @"/";
|
2006-10-18 16:42:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* priorities */
|
|
|
|
|
|
|
|
- (NSArray *) priorities
|
|
|
|
{
|
|
|
|
/* 0 == undefined
|
|
|
|
5 == normal
|
|
|
|
1 == high
|
|
|
|
*/
|
|
|
|
static NSArray *priorities = nil;
|
|
|
|
|
|
|
|
if (!priorities)
|
|
|
|
{
|
2007-03-18 16:20:38 +01:00
|
|
|
priorities = [NSArray arrayWithObjects: @"0", @"5", @"1", nil];
|
2006-10-18 16:42:44 +02:00
|
|
|
[priorities retain];
|
|
|
|
}
|
|
|
|
|
|
|
|
return priorities;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) setPriority: (NSString *) _priority
|
|
|
|
{
|
2007-03-18 16:20:38 +01:00
|
|
|
ASSIGN (priority, _priority);
|
2006-10-18 16:42:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *) priority
|
|
|
|
{
|
|
|
|
return priority;
|
|
|
|
}
|
|
|
|
|
2006-11-03 20:38:08 +01:00
|
|
|
- (NSArray *) privacyClasses
|
|
|
|
{
|
|
|
|
static NSArray *priorities = nil;
|
|
|
|
|
|
|
|
if (!priorities)
|
|
|
|
{
|
2006-11-03 22:18:03 +01:00
|
|
|
priorities = [NSArray arrayWithObjects: @"PUBLIC",
|
|
|
|
@"CONFIDENTIAL", @"PRIVATE", nil];
|
2006-11-03 20:38:08 +01:00
|
|
|
[priorities retain];
|
|
|
|
}
|
|
|
|
|
|
|
|
return priorities;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) setPrivacy: (NSString *) _privacy
|
|
|
|
{
|
2007-03-18 16:20:38 +01:00
|
|
|
ASSIGN (privacy, _privacy);
|
2006-11-03 20:38:08 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *) privacy
|
|
|
|
{
|
|
|
|
return privacy;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSArray *) statusTypes
|
|
|
|
{
|
|
|
|
static NSArray *priorities = nil;
|
|
|
|
|
|
|
|
if (!priorities)
|
|
|
|
{
|
|
|
|
priorities = [NSArray arrayWithObjects: @"", @"TENTATIVE", @"CONFIRMED", @"CANCELLED", nil];
|
|
|
|
[priorities retain];
|
|
|
|
}
|
|
|
|
|
|
|
|
return priorities;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) setStatus: (NSString *) _status
|
|
|
|
{
|
2007-03-18 16:20:38 +01:00
|
|
|
ASSIGN (status, _status);
|
2006-11-03 20:38:08 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *) status
|
|
|
|
{
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
2006-10-18 16:42:44 +02:00
|
|
|
- (NSArray *) cycles
|
|
|
|
{
|
|
|
|
NSBundle *bundle;
|
|
|
|
NSString *path;
|
|
|
|
static NSArray *cycles = nil;
|
|
|
|
|
|
|
|
if (!cycles)
|
|
|
|
{
|
|
|
|
bundle = [NSBundle bundleForClass:[self class]];
|
2007-03-18 16:20:38 +01:00
|
|
|
path = [bundle pathForResource: @"cycles" ofType: @"plist"];
|
2006-10-18 16:42:44 +02:00
|
|
|
NSAssert(path != nil, @"Cannot find cycles.plist!");
|
|
|
|
cycles = [[NSArray arrayWithContentsOfFile:path] retain];
|
|
|
|
NSAssert(cycles != nil, @"Cannot instantiate cycles from cycles.plist!");
|
|
|
|
}
|
|
|
|
|
|
|
|
return cycles;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) setCycle: (NSDictionary *) _cycle
|
|
|
|
{
|
2007-03-18 16:20:38 +01:00
|
|
|
ASSIGN (cycle, _cycle);
|
2006-10-18 16:42:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
- (NSDictionary *) cycle
|
|
|
|
{
|
|
|
|
return cycle;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL) hasCycle
|
|
|
|
{
|
|
|
|
return ([cycle objectForKey: @"rule"] != nil);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *) cycleLabel
|
|
|
|
{
|
|
|
|
NSString *key;
|
|
|
|
|
2007-03-18 16:20:38 +01:00
|
|
|
key = [(NSDictionary *)item objectForKey: @"label"];
|
2006-10-18 16:42:44 +02:00
|
|
|
|
|
|
|
return [self labelForKey:key];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) setCycleUntilDate: (NSCalendarDate *) _cycleUntilDate
|
|
|
|
{
|
2007-03-18 16:20:38 +01:00
|
|
|
// NSCalendarDate *until;
|
2006-10-18 16:42:44 +02:00
|
|
|
|
2007-03-18 16:20:38 +01:00
|
|
|
// /* copy hour/minute/second from startDate */
|
|
|
|
// until = [_cycleUntilDate hour: [startDate hourOfDay]
|
|
|
|
// minute: [startDate minuteOfHour]
|
|
|
|
// second: [startDate secondOfMinute]];
|
|
|
|
// [until setTimeZone: [startDate timeZone]];
|
|
|
|
// ASSIGN (cycleUntilDate, until);
|
2006-10-18 16:42:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
- (NSCalendarDate *) cycleUntilDate
|
|
|
|
{
|
|
|
|
return cycleUntilDate;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (iCalRecurrenceRule *) rrule
|
|
|
|
{
|
|
|
|
NSString *ruleRep;
|
|
|
|
iCalRecurrenceRule *rule;
|
|
|
|
|
|
|
|
if (![self hasCycle])
|
|
|
|
return nil;
|
2007-03-18 16:20:38 +01:00
|
|
|
ruleRep = [cycle objectForKey: @"rule"];
|
2006-10-18 16:42:44 +02:00
|
|
|
rule = [iCalRecurrenceRule recurrenceRuleWithICalRepresentation:ruleRep];
|
|
|
|
|
|
|
|
if (cycleUntilDate && [self isCycleEndUntil])
|
|
|
|
[rule setUntilDate:cycleUntilDate];
|
|
|
|
|
|
|
|
return rule;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) adjustCycleControlsForRRule: (iCalRecurrenceRule *) _rrule
|
|
|
|
{
|
2007-03-18 16:20:38 +01:00
|
|
|
// NSDictionary *c;
|
|
|
|
// NSCalendarDate *until;
|
2006-10-18 16:42:44 +02:00
|
|
|
|
2007-03-18 16:20:38 +01:00
|
|
|
// c = [self cycleMatchingRRule:_rrule];
|
|
|
|
// [self setCycle:c];
|
2006-10-18 16:42:44 +02:00
|
|
|
|
2007-03-18 16:20:38 +01:00
|
|
|
// until = [[[_rrule untilDate] copy] autorelease];
|
|
|
|
// if (!until)
|
|
|
|
// until = startDate;
|
|
|
|
// else
|
|
|
|
// [self setIsCycleEndUntil];
|
2006-10-18 16:42:44 +02:00
|
|
|
|
2007-03-18 16:20:38 +01:00
|
|
|
// [until setTimeZone:[[self clientObject] userTimeZone]];
|
|
|
|
// [self setCycleUntilDate:until];
|
2006-10-18 16:42:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
This method is necessary, because we have a fixed sets of cycles in the UI.
|
|
|
|
The model is able to represent arbitrary rules, however.
|
|
|
|
There SHOULD be a different UI, similar to iCal.app, to allow modelling
|
|
|
|
of more complex rules.
|
|
|
|
|
|
|
|
This method obviously cannot map all existing rules back to the fixed list
|
|
|
|
in cycles.plist. This should be fixed in a future version when interop
|
|
|
|
becomes more important.
|
|
|
|
*/
|
|
|
|
- (NSDictionary *) cycleMatchingRRule: (iCalRecurrenceRule *) _rrule
|
|
|
|
{
|
|
|
|
NSString *cycleRep;
|
|
|
|
NSArray *cycles;
|
|
|
|
unsigned i, count;
|
|
|
|
|
|
|
|
if (!_rrule)
|
|
|
|
return [[self cycles] objectAtIndex:0];
|
|
|
|
|
|
|
|
cycleRep = [_rrule versitString];
|
|
|
|
cycles = [self cycles];
|
|
|
|
count = [cycles count];
|
|
|
|
for (i = 1; i < count; i++) {
|
|
|
|
NSDictionary *c;
|
|
|
|
NSString *cr;
|
|
|
|
|
|
|
|
c = [cycles objectAtIndex:i];
|
2007-03-18 16:20:38 +01:00
|
|
|
cr = [c objectForKey: @"rule"];
|
2006-10-18 16:42:44 +02:00
|
|
|
if ([cr isEqualToString:cycleRep])
|
|
|
|
return c;
|
|
|
|
}
|
2007-03-18 16:20:38 +01:00
|
|
|
[self warnWithFormat: @"No default cycle for rrule found! -> %@", _rrule];
|
2006-10-18 16:42:44 +02:00
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* cycle "ends" - supposed to be 'never', 'COUNT' or 'UNTIL' */
|
|
|
|
- (NSArray *) cycleEnds
|
|
|
|
{
|
|
|
|
static NSArray *ends = nil;
|
|
|
|
|
|
|
|
if (!ends)
|
|
|
|
{
|
|
|
|
ends = [NSArray arrayWithObjects: @"cycle_end_never",
|
|
|
|
@"cycle_end_until", nil];
|
|
|
|
[ends retain];
|
|
|
|
}
|
|
|
|
|
|
|
|
return ends;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) setCycleEnd: (NSString *) _cycleEnd
|
|
|
|
{
|
2007-03-18 16:20:38 +01:00
|
|
|
ASSIGN (cycleEnd, _cycleEnd);
|
2006-10-18 16:42:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *) cycleEnd
|
|
|
|
{
|
|
|
|
return cycleEnd;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL) isCycleEndUntil
|
|
|
|
{
|
2007-03-18 16:20:38 +01:00
|
|
|
return (cycleEnd && [cycleEnd isEqualToString: @"cycle_end_until"]);
|
2006-10-18 16:42:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void) setIsCycleEndUntil
|
|
|
|
{
|
2007-03-18 16:20:38 +01:00
|
|
|
[self setCycleEnd: @"cycle_end_until"];
|
2006-10-18 16:42:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void) setIsCycleEndNever
|
|
|
|
{
|
2007-03-18 16:20:38 +01:00
|
|
|
[self setCycleEnd: @"cycle_end_never"];
|
2006-10-18 16:42:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* helpers */
|
|
|
|
- (NSString *) completeURIForMethod: (NSString *) _method
|
|
|
|
{
|
|
|
|
NSString *uri;
|
|
|
|
NSRange r;
|
|
|
|
|
|
|
|
uri = [[[self context] request] uri];
|
|
|
|
|
|
|
|
/* first: identify query parameters */
|
2007-03-18 16:20:38 +01:00
|
|
|
r = [uri rangeOfString: @"?" options:NSBackwardsSearch];
|
2006-10-18 16:42:44 +02:00
|
|
|
if (r.length > 0)
|
|
|
|
uri = [uri substringToIndex:r.location];
|
|
|
|
|
|
|
|
/* next: append trailing slash */
|
2007-03-18 16:20:38 +01:00
|
|
|
if (![uri hasSuffix: @"/"])
|
|
|
|
uri = [uri stringByAppendingString: @"/"];
|
2006-10-18 16:42:44 +02:00
|
|
|
|
|
|
|
/* next: append method */
|
|
|
|
uri = [uri stringByAppendingString:_method];
|
|
|
|
|
|
|
|
/* next: append query parameters */
|
|
|
|
return [self completeHrefForMethod:uri];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL) isWriteableClientObject
|
|
|
|
{
|
|
|
|
return [[self clientObject]
|
2007-03-18 16:20:38 +01:00
|
|
|
respondsToSelector: @selector(saveContentString:)];
|
2006-10-18 16:42:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL) containsConflict: (id) _component
|
|
|
|
{
|
|
|
|
[self subclassResponsibility: _cmd];
|
|
|
|
|
|
|
|
return NO;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* access */
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
- (iCalPerson *) getOrganizer
|
|
|
|
{
|
|
|
|
iCalPerson *p;
|
|
|
|
NSString *emailProp;
|
|
|
|
|
2006-11-07 17:15:20 +01:00
|
|
|
emailProp = [@"MAILTO:" stringByAppendingString:[self emailForUser]];
|
2006-10-18 16:42:44 +02:00
|
|
|
p = [[[iCalPerson alloc] init] autorelease];
|
|
|
|
[p setEmail:emailProp];
|
|
|
|
[p setCn:[self cnForUser]];
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
- (BOOL) isMyComponent
|
|
|
|
{
|
2007-05-09 21:23:45 +02:00
|
|
|
return ([[context activeUser] hasEmail: [organizer rfc822Email]]);
|
2006-10-18 16:42:44 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL) canEditComponent
|
|
|
|
{
|
|
|
|
return [self isMyComponent];
|
|
|
|
}
|
|
|
|
|
|
|
|
/* response generation */
|
|
|
|
|
|
|
|
- (NSString *) initialCycleVisibility
|
|
|
|
{
|
|
|
|
return ([self hasCycle]
|
|
|
|
? @"visibility: visible;"
|
|
|
|
: @"visibility: hidden;");
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSString *) initialCycleEndUntilVisibility {
|
|
|
|
return ([self isCycleEndUntil]
|
|
|
|
? @"visibility: visible;"
|
|
|
|
: @"visibility: hidden;");
|
|
|
|
}
|
|
|
|
|
2007-04-17 15:49:23 +02:00
|
|
|
// - (NSString *) iCalParticipantsAndResourcesStringFromQueryParameters
|
|
|
|
// {
|
|
|
|
// NSString *s;
|
2006-10-18 16:42:44 +02:00
|
|
|
|
2007-04-17 15:49:23 +02:00
|
|
|
// s = [self iCalParticipantsStringFromQueryParameters];
|
|
|
|
// return [s stringByAppendingString:
|
|
|
|
// [self iCalResourcesStringFromQueryParameters]];
|
|
|
|
// }
|
|
|
|
|
|
|
|
// - (NSString *) iCalParticipantsStringFromQueryParameters
|
|
|
|
// {
|
|
|
|
// static NSString *iCalParticipantString = @"ATTENDEE;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;CN=\"%@\":MAILTO:%@\r\n";
|
2006-10-18 16:42:44 +02:00
|
|
|
|
2007-04-17 15:49:23 +02:00
|
|
|
// return [self iCalStringFromQueryParameter: @"ps"
|
|
|
|
// format: iCalParticipantString];
|
|
|
|
// }
|
|
|
|
|
|
|
|
// - (NSString *) iCalResourcesStringFromQueryParameters
|
|
|
|
// {
|
|
|
|
// static NSString *iCalResourceString = @"ATTENDEE;ROLE=NON-PARTICIPANT;CN=\"%@\":MAILTO:%@\r\n";
|
|
|
|
|
|
|
|
// return [self iCalStringFromQueryParameter: @"rs"
|
|
|
|
// format: iCalResourceString];
|
|
|
|
// }
|
|
|
|
|
|
|
|
// - (NSString *) iCalStringFromQueryParameter: (NSString *) _qp
|
|
|
|
// format: (NSString *) _format
|
|
|
|
// {
|
|
|
|
// AgenorUserManager *um;
|
|
|
|
// NSMutableString *iCalRep;
|
|
|
|
// NSString *s;
|
|
|
|
|
|
|
|
// um = [AgenorUserManager sharedUserManager];
|
|
|
|
// iCalRep = (NSMutableString *)[NSMutableString string];
|
|
|
|
// s = [self queryParameterForKey:_qp];
|
|
|
|
// if(s && [s length] > 0) {
|
|
|
|
// NSArray *es;
|
|
|
|
// unsigned i, count;
|
2006-10-18 16:42:44 +02:00
|
|
|
|
2007-04-17 15:49:23 +02:00
|
|
|
// es = [s componentsSeparatedByString: @","];
|
|
|
|
// count = [es count];
|
|
|
|
// for(i = 0; i < count; i++) {
|
|
|
|
// NSString *email, *cn;
|
2006-10-18 16:42:44 +02:00
|
|
|
|
2007-04-17 15:49:23 +02:00
|
|
|
// email = [es objectAtIndex:i];
|
|
|
|
// cn = [um getCNForUID:[um getUIDForEmail:email]];
|
|
|
|
// [iCalRep appendFormat:_format, cn, email];
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
// return iCalRep;
|
|
|
|
// }
|
2006-10-18 16:42:44 +02:00
|
|
|
|
|
|
|
- (NSException *) validateObjectForStatusChange
|
|
|
|
{
|
|
|
|
id co;
|
|
|
|
|
|
|
|
co = [self clientObject];
|
2007-04-17 15:49:23 +02:00
|
|
|
if (![co respondsToSelector: @selector(changeParticipationStatus:)])
|
|
|
|
return [NSException exceptionWithHTTPStatus: 400 /* Bad Request */
|
2006-10-18 16:42:44 +02:00
|
|
|
reason:
|
|
|
|
@"method cannot be invoked on the specified object"];
|
|
|
|
|
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* contact editor compatibility */
|
|
|
|
|
2006-10-23 23:34:56 +02:00
|
|
|
- (NSString *) urlButtonClasses
|
|
|
|
{
|
|
|
|
NSString *classes;
|
|
|
|
|
|
|
|
if ([url length])
|
|
|
|
classes = @"button";
|
|
|
|
else
|
|
|
|
classes = @"button _disabled";
|
|
|
|
|
|
|
|
return classes;
|
|
|
|
}
|
|
|
|
|
2007-03-18 16:20:38 +01:00
|
|
|
- (void) _handleAttendeesEdition
|
2006-11-07 19:15:29 +01:00
|
|
|
{
|
2007-03-18 16:20:38 +01:00
|
|
|
NSArray *names, *emails;
|
|
|
|
NSMutableArray *newAttendees;
|
|
|
|
unsigned int count, max;
|
|
|
|
NSString *currentEmail;
|
|
|
|
iCalPerson *currentAttendee;
|
2006-11-07 19:15:29 +01:00
|
|
|
|
2007-03-18 16:20:38 +01:00
|
|
|
newAttendees = [NSMutableArray new];
|
2007-03-19 15:33:33 +01:00
|
|
|
if ([attendeesNames length] > 0)
|
2006-11-07 19:15:29 +01:00
|
|
|
{
|
2007-03-19 15:33:33 +01:00
|
|
|
names = [attendeesNames componentsSeparatedByString: @","];
|
|
|
|
emails = [attendeesEmails componentsSeparatedByString: @","];
|
|
|
|
max = [emails count];
|
|
|
|
for (count = 0; count < max; count++)
|
|
|
|
{
|
|
|
|
currentEmail = [emails objectAtIndex: count];
|
|
|
|
currentAttendee = [component findParticipantWithEmail: currentEmail];
|
|
|
|
if (!currentAttendee)
|
|
|
|
{
|
|
|
|
currentAttendee = [iCalPerson elementWithTag: @"attendee"];
|
|
|
|
[currentAttendee setCn: [names objectAtIndex: count]];
|
|
|
|
[currentAttendee setEmail: currentEmail];
|
|
|
|
[currentAttendee setRole: @"REQ-PARTICIPANT"];
|
|
|
|
[currentAttendee
|
|
|
|
setParticipationStatus: iCalPersonPartStatNeedsAction];
|
|
|
|
}
|
|
|
|
[newAttendees addObject: currentAttendee];
|
|
|
|
}
|
2006-11-07 20:24:36 +01:00
|
|
|
}
|
|
|
|
|
2007-03-18 16:20:38 +01:00
|
|
|
[component setAttendees: newAttendees];
|
|
|
|
[newAttendees release];
|
2006-11-07 20:24:36 +01:00
|
|
|
}
|
|
|
|
|
2007-03-19 15:33:33 +01:00
|
|
|
- (void) _handleOrganizer
|
|
|
|
{
|
|
|
|
NSString *organizerEmail;
|
2007-05-09 21:23:45 +02:00
|
|
|
SOGoUser *activeUser;
|
2007-08-15 22:13:41 +02:00
|
|
|
NSDictionary *primaryIdentity;
|
2007-03-19 15:33:33 +01:00
|
|
|
|
|
|
|
organizerEmail = [[component organizer] email];
|
|
|
|
if ([organizerEmail length] == 0)
|
|
|
|
{
|
|
|
|
if ([[component attendees] count] > 0)
|
|
|
|
{
|
|
|
|
ASSIGN (organizer, [iCalPerson elementWithTag: @"organizer"]);
|
2007-05-09 21:23:45 +02:00
|
|
|
activeUser = [context activeUser];
|
2007-08-15 22:13:41 +02:00
|
|
|
primaryIdentity = [activeUser primaryIdentity];
|
2007-05-09 21:23:45 +02:00
|
|
|
[organizer setCn: [activeUser cn]];
|
2007-08-15 22:13:41 +02:00
|
|
|
[organizer setEmail: [primaryIdentity objectForKey: @"email"]];
|
2007-03-19 15:33:33 +01:00
|
|
|
[component setOrganizer: organizer];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ([[component attendees] count] == 0)
|
|
|
|
{
|
|
|
|
ASSIGN (organizer, [iCalPerson elementWithTag: @"organizer"]);
|
|
|
|
[component setOrganizer: organizer];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-03-18 16:20:38 +01:00
|
|
|
- (void) takeValuesFromRequest: (WORequest *) _rq
|
|
|
|
inContext: (WOContext *) _ctx
|
2006-11-07 20:24:36 +01:00
|
|
|
{
|
2007-03-18 16:20:38 +01:00
|
|
|
NSCalendarDate *now;
|
2007-03-27 20:18:06 +02:00
|
|
|
SOGoCalendarComponent *clientObject;
|
2007-03-18 16:20:38 +01:00
|
|
|
|
|
|
|
[super takeValuesFromRequest: _rq inContext: _ctx];
|
2006-11-07 20:24:36 +01:00
|
|
|
|
2007-03-18 16:20:38 +01:00
|
|
|
now = [NSCalendarDate calendarDate];
|
|
|
|
[component setSummary: title];
|
|
|
|
[component setLocation: location];
|
|
|
|
[component setComment: comment];
|
|
|
|
[component setUrl: url];
|
2007-04-26 03:16:19 +02:00
|
|
|
[component setAccessClass: privacy];
|
2007-03-19 15:33:33 +01:00
|
|
|
[self _handleAttendeesEdition];
|
|
|
|
[self _handleOrganizer];
|
2007-03-27 20:18:06 +02:00
|
|
|
clientObject = [self clientObject];
|
|
|
|
if ([clientObject isNew])
|
2006-11-07 20:24:36 +01:00
|
|
|
{
|
2007-03-27 20:18:06 +02:00
|
|
|
[component setUid: [clientObject nameInContainer]];
|
2007-03-18 16:20:38 +01:00
|
|
|
[component setCreated: now];
|
|
|
|
[component setTimeStampAsDate: now];
|
|
|
|
[component setPriority: @"0"];
|
2006-11-07 19:15:29 +01:00
|
|
|
}
|
2007-03-18 16:20:38 +01:00
|
|
|
[component setLastModified: now];
|
2006-11-07 19:15:29 +01:00
|
|
|
}
|
|
|
|
|
2007-05-03 18:13:51 +02:00
|
|
|
- (NSString *) toolbar
|
|
|
|
{
|
|
|
|
SOGoCalendarComponent *clientObject;
|
|
|
|
NSString *toolbarFilename;
|
2007-06-05 20:07:08 +02:00
|
|
|
iCalPerson *participant;
|
2007-05-03 18:13:51 +02:00
|
|
|
iCalPersonPartStat participationStatus;
|
2007-06-01 23:01:44 +02:00
|
|
|
SoSecurityManager *sm;
|
|
|
|
NSString *owner;
|
2007-05-03 18:13:51 +02:00
|
|
|
|
2007-06-01 23:01:44 +02:00
|
|
|
sm = [SoSecurityManager sharedSecurityManager];
|
2007-05-03 18:13:51 +02:00
|
|
|
clientObject = [self clientObject];
|
2007-06-01 23:01:44 +02:00
|
|
|
|
2007-06-05 20:07:08 +02:00
|
|
|
owner = [clientObject ownerInContext: context];
|
|
|
|
participant = [clientObject findParticipantWithUID: owner];
|
|
|
|
|
|
|
|
if (participant
|
|
|
|
&& ![sm validatePermission: SOGoCalendarPerm_RespondToComponent
|
|
|
|
onObject: clientObject
|
|
|
|
inContext: context])
|
2007-05-03 18:13:51 +02:00
|
|
|
{
|
2007-06-05 20:07:08 +02:00
|
|
|
participationStatus = [participant participationStatus];
|
2007-05-03 18:13:51 +02:00
|
|
|
/* Lightning does not manage participation status within tasks */
|
2007-06-01 23:01:44 +02:00
|
|
|
if (participationStatus == iCalPersonPartStatAccepted)
|
|
|
|
toolbarFilename = @"SOGoAppointmentObjectDecline.toolbar";
|
|
|
|
else if (participationStatus == iCalPersonPartStatDeclined)
|
|
|
|
toolbarFilename = @"SOGoAppointmentObjectAccept.toolbar";
|
2007-05-03 18:13:51 +02:00
|
|
|
else
|
2007-06-01 23:01:44 +02:00
|
|
|
toolbarFilename = @"SOGoAppointmentObjectAcceptOrDecline.toolbar";
|
2007-05-03 18:13:51 +02:00
|
|
|
}
|
2007-06-05 20:07:08 +02:00
|
|
|
else if (![sm validatePermission: SOGoCalendarPerm_ModifyComponent
|
|
|
|
onObject: clientObject
|
|
|
|
inContext: context])
|
|
|
|
{
|
|
|
|
if ([[clientObject componentTag] isEqualToString: @"vevent"])
|
|
|
|
toolbarFilename = @"SOGoAppointmentObject.toolbar";
|
|
|
|
else
|
|
|
|
toolbarFilename = @"SOGoTaskObject.toolbar";
|
|
|
|
}
|
2007-06-01 23:01:44 +02:00
|
|
|
else
|
|
|
|
toolbarFilename = @"SOGoComponentClose.toolbar";
|
2007-05-03 18:13:51 +02:00
|
|
|
|
|
|
|
return toolbarFilename;
|
|
|
|
}
|
|
|
|
|
2006-10-18 16:42:44 +02:00
|
|
|
@end
|