From 28aeaa6fee8bc6c88fb6b680df0417072a2c7bdc Mon Sep 17 00:00:00 2001 From: Ludovic Marcotte Date: Tue, 30 Dec 2008 19:48:33 +0000 Subject: [PATCH] See ChangeLog Monotone-Parent: cf113a40bd52153bf7981b492915e149294e2c84 Monotone-Revision: f68bc0f7c4af372fd5c49f8961ad1605dd875d1f Monotone-Author: ludovic@Sophos.ca Monotone-Date: 2008-12-30T19:48:33 Monotone-Branch: ca.inverse.sogo --- ChangeLog | 11 + .../Appointments/SOGoAppointmentFolder.m | 7 +- SoObjects/Contacts/SOGoContactGCSFolder.m | 2 + SoObjects/SOGo/SOGoUser.h | 1 + SoObjects/SOGo/SOGoUser.m | 1 + UI/Scheduler/GNUmakefile | 2 - UI/Scheduler/UIxAppointmentProposal.m | 510 ----------------- UI/Scheduler/UIxTaskProposal.m | 515 ------------------ UI/Scheduler/product.plist | 9 - UI/WebServerResources/SchedulerUI.js | 2 +- 10 files changed, 20 insertions(+), 1040 deletions(-) delete mode 100644 UI/Scheduler/UIxAppointmentProposal.m delete mode 100644 UI/Scheduler/UIxTaskProposal.m diff --git a/ChangeLog b/ChangeLog index 3d36fb7ef..8626d7f85 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2008-12-30 Ludovic Marcotte + + * Dropped the following files: + UI/Scheduler/UIxAppointmentProposal.m + UI/Scheduler/UIxTaskProposal.m + * SoObjects/Appointments/SOGoAppointmentFolder.m + SoObjects/Contacts/SOGoContactGCSFolder.m + UI/WebServerResources/SchedulerUI.js + Fixed the escaping of characters and associated + search methods. + 2008-12-30 Francis Lachapelle * SoObjects/Appointments/SOGoAppointmentObject.m diff --git a/SoObjects/Appointments/SOGoAppointmentFolder.m b/SoObjects/Appointments/SOGoAppointmentFolder.m index 17345a95a..6ceb9f970 100644 --- a/SoObjects/Appointments/SOGoAppointmentFolder.m +++ b/SoObjects/Appointments/SOGoAppointmentFolder.m @@ -1,6 +1,6 @@ /* - Copyright (C) 2004-2005 SKYRIX Software AG Copyright (C) 2007-2008 Inverse inc. + Copyright (C) 2004-2005 SKYRIX Software AG This file is part of OpenGroupware.org. @@ -968,7 +968,8 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir if ([title length]) titleSqlString = [NSString stringWithFormat: @"AND (c_title" - @" isCaseInsensitiveLike: '%%%@%%')", title]; + @" isCaseInsensitiveLike: '%%%@%%')", + [title stringByReplacingString: @"'" withString: @"\\'\\'"]]; else titleSqlString = @""; @@ -2267,7 +2268,7 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir infos = [[NSArray alloc] initWithObjects: @"c_partmails", @"c_partstates", @"c_isopaque", @"c_status", @"c_cycleinfo", @"c_orgmail", nil]; - // We MUST include the protected information whenc checking for freebusy info as + // We MUST include the protected information when checking for freebusy info as // we rely on the c_partmails/c_partstates fields for many operations. return [self fetchFields: infos from: _startDate to: _endDate diff --git a/SoObjects/Contacts/SOGoContactGCSFolder.m b/SoObjects/Contacts/SOGoContactGCSFolder.m index 19eb1f405..927a4adaa 100644 --- a/SoObjects/Contacts/SOGoContactGCSFolder.m +++ b/SoObjects/Contacts/SOGoContactGCSFolder.m @@ -1,4 +1,5 @@ /* + Copyright (C) 2006-2009 Inverse inc. Copyright (C) 2004-2005 SKYRIX Software AG This file is part of OpenGroupware.org. @@ -215,6 +216,7 @@ if (filter && [filter length] > 0) { + filter = [filter stringByReplacingString: @"'" withString: @"\\'\\'"]; qs = [NSString stringWithFormat: @"(c_sn isCaseInsensitiveLike: '%@%%') OR " @"(c_givenname isCaseInsensitiveLike: '%@%%') OR " diff --git a/SoObjects/SOGo/SOGoUser.h b/SoObjects/SOGo/SOGoUser.h index cbefa92be..8c3dace3e 100644 --- a/SoObjects/SOGo/SOGoUser.h +++ b/SoObjects/SOGo/SOGoUser.h @@ -1,4 +1,5 @@ /* + Copyright (C) 2006-2009 Inverse inc. Copyright (C) 2005 SKYRIX Software AG This file is part of OpenGroupware.org. diff --git a/SoObjects/SOGo/SOGoUser.m b/SoObjects/SOGo/SOGoUser.m index 617a971ec..bdb238e7d 100644 --- a/SoObjects/SOGo/SOGoUser.m +++ b/SoObjects/SOGo/SOGoUser.m @@ -1,4 +1,5 @@ /* + Copyright (C) 2006-2009 Inverse inc. Copyright (C) 2005 SKYRIX Software AG This file is part of OpenGroupware.org. diff --git a/UI/Scheduler/GNUmakefile b/UI/Scheduler/GNUmakefile index d804ccfca..f82f5c54f 100644 --- a/UI/Scheduler/GNUmakefile +++ b/UI/Scheduler/GNUmakefile @@ -44,8 +44,6 @@ SchedulerUI_OBJC_FILES = \ UIxCalMonthViewOld.m \ UIxRecurrenceEditor.m \ UIxOccurenceDialog.m -# UIxAppointmentProposal.m -# UIxTaskProposal.m SchedulerUI_RESOURCE_FILES += \ Version \ diff --git a/UI/Scheduler/UIxAppointmentProposal.m b/UI/Scheduler/UIxAppointmentProposal.m deleted file mode 100644 index c8b65ac8e..000000000 --- a/UI/Scheduler/UIxAppointmentProposal.m +++ /dev/null @@ -1,510 +0,0 @@ -/* - Copyright (C) 2004 SKYRIX Software AG - - This file is part of OpenGroupware.org. - - OGo is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - OGo is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with OGo; see the file COPYING. If not, write to the - Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. -*/ - -#import -#import -#import - -#import -#import -#import - -#import -#import -#import - -@interface UIxAppointmentProposal : UIxComponent -{ - id item; - id currentDay; - - /* individual values */ - id startDateHour; - id startDateMinute; - id endDateHour; - id endDateMinute; - - id startDateDay; - id startDateMonth; - id startDateYear; - id endDateDay; - id endDateMonth; - id endDateYear; - - NSArray *participants; /* array of iCalPerson's */ - NSArray *resources; /* array of iCalPerson's */ - id duration; - - NSArray *blockedRanges; - NSMutableDictionary *currentQueryParameters; -} - -- (NSMutableDictionary *)currentQueryParameters; -- (NSDictionary *)currentHourQueryParametersForFirstHalf:(BOOL)_first; - -- (void)setICalPersons:(NSArray *)_ps asQueryParameter:(NSString *)_qp; -@end - -@implementation UIxAppointmentProposal - -- (void)dealloc { - [self->blockedRanges release]; - - [self->startDateHour release]; - [self->startDateMinute release]; - [self->startDateDay release]; - [self->startDateMonth release]; - [self->startDateYear release]; - - [self->endDateHour release]; - [self->endDateMinute release]; - [self->endDateDay release]; - [self->endDateMonth release]; - [self->endDateYear release]; - [self->duration release]; - - [self->participants release]; - [self->resources release]; - - [self->currentQueryParameters release]; - [super dealloc]; -} - -/* notifications */ - -- (void)sleep { - [self->currentDay release]; self->currentDay = nil; - [self->item release]; self->item = nil; - [super sleep]; -} - -/* accessors */ - -- (void)setItem:(id)_item { - ASSIGN(self->item, _item); -} -- (id)item { - return self->item; -} - -- (void)setStartDateHour:(id)_startDateHour { - ASSIGN(self->startDateHour, _startDateHour); -} -- (id)startDateHour { - return self->startDateHour; -} -- (void)setStartDateMinute:(id)_startDateMinute { - ASSIGN(self->startDateMinute, _startDateMinute); -} -- (id)startDateMinute { - return self->startDateMinute; -} -- (void)setStartDateDay:(id)_startDateDay { - ASSIGN(self->startDateDay, _startDateDay); -} -- (id)startDateDay { - return self->startDateDay; -} -- (void)setStartDateMonth:(id)_startDateMonth { - ASSIGN(self->startDateMonth, _startDateMonth); -} -- (id)startDateMonth { - return self->startDateMonth; -} -- (void)setStartDateYear:(id)_startDateYear { - ASSIGN(self->startDateYear, _startDateYear); -} -- (id)startDateYear { - return self->startDateYear; -} -- (void)setEndDateHour:(id)_endDateHour { - ASSIGN(self->endDateHour, _endDateHour); -} -- (id)endDateHour { - return self->endDateHour; -} -- (void)setEndDateMinute:(id)_endDateMinute { - ASSIGN(self->endDateMinute, _endDateMinute); -} -- (id)endDateMinute { - return self->endDateMinute; -} -- (void)setEndDateDay:(id)_endDateDay { - ASSIGN(self->endDateDay, _endDateDay); -} -- (id)endDateDay { - return self->endDateDay; -} -- (void)setEndDateMonth:(id)_endDateMonth { - ASSIGN(self->endDateMonth, _endDateMonth); -} -- (id)endDateMonth { - return self->endDateMonth; -} -- (void)setEndDateYear:(id)_endDateYear { - ASSIGN(self->endDateYear, _endDateYear); -} -- (id)endDateYear { - return self->endDateYear; -} - -- (void)setStartDate:(NSCalendarDate *)_date { - [self setStartDateHour:[NSNumber numberWithInt:[_date hourOfDay]]]; - [self setStartDateMinute:[NSNumber numberWithInt:[_date minuteOfHour]]]; - [self setStartDateDay:[NSNumber numberWithInt:[_date dayOfMonth]]]; - [self setStartDateMonth:[NSNumber numberWithInt:[_date monthOfYear]]]; - [self setStartDateYear:[NSNumber numberWithInt:[_date yearOfCommonEra]]]; -} - -- (NSCalendarDate *) startDate -{ - NSTimeZone *timeZone; - - timeZone = [[context activeUser] timeZone]; - - return [NSCalendarDate dateWithYear:[[self startDateYear] intValue] - month:[[self startDateMonth] intValue] - day:[[self startDateDay] intValue] - hour:[[self startDateHour] intValue] - minute:[[self startDateMinute] intValue] - second:0 - timeZone: timeZone]; -} - -- (void) setEndDate: (NSCalendarDate *) _date -{ - [self setEndDateHour:[NSNumber numberWithInt:[_date hourOfDay]]]; - [self setEndDateMinute:[NSNumber numberWithInt:[_date minuteOfHour]]]; - [self setEndDateDay:[NSNumber numberWithInt:[_date dayOfMonth]]]; - [self setEndDateMonth:[NSNumber numberWithInt:[_date monthOfYear]]]; - [self setEndDateYear:[NSNumber numberWithInt:[_date yearOfCommonEra]]]; -} - -- (NSCalendarDate *) endDate -{ - NSTimeZone *timeZone; - - timeZone = [[context activeUser] timeZone]; - - return [NSCalendarDate dateWithYear:[[self endDateYear] intValue] - month:[[self endDateMonth] intValue] - day:[[self endDateDay] intValue] - hour:[[self endDateHour] intValue] - minute:[[self endDateMinute] intValue] - second:59 - timeZone: timeZone]; -} - -- (void)setDuration:(id)_duration { - ASSIGN(self->duration, _duration); -} -- (id)duration { - return self->duration; -} -- (int)durationInMinutes { - return [[self duration] intValue]; -} -- (NSTimeInterval)durationAsTimeInterval { - return [self durationInMinutes] * 60; -} - -- (NSString *)itemDurationText { - // TODO: use a formatter - // TODO: localize - switch ([[self item] intValue]) { - case 30: return @"30 minutes"; - case 60: return @"1 hour"; - case 120: return @"2 hours"; - case 240: return @"4 hours"; - case 480: return @"8 hours"; - default: - return [NSString stringWithFormat:@"%@ minutes", [self item]]; - } -} - -- (void)setParticipants:(NSArray *)_parts { - ASSIGN(self->participants, _parts); -} -- (NSArray *)participants { - return self->participants; -} -- (void)setResources:(NSArray *)_res { - ASSIGN(self->resources, _res); -} -- (NSArray *)resources { - return self->resources; -} - -- (NSArray *)attendees { - NSArray *a, *b; - - a = [self participants]; - b = [self resources]; - if ([b count] == 0) return a; - if ([a count] == 0) return b; - return [a arrayByAddingObjectsFromArray:b]; -} - -- (void)setCurrentDay:(id)_day { - ASSIGN(self->currentDay, _day); -} -- (id)currentDay { - return self->currentDay; -} - -- (NSArray *)hours { - // TODO: from 'earliest start' to 'latest endtime' - unsigned lStartHour = 9, lEndHour = 17, i; - NSMutableArray *ma; - - lStartHour = [[self startDateHour] intValue]; - lEndHour = [[self endDateHour] intValue]; - if (lStartHour < 1) lStartHour = 1; - if (lEndHour < lStartHour) lEndHour = lStartHour + 1; - - ma = [NSMutableArray arrayWithCapacity:lEndHour - lStartHour + 2]; - for (i = lStartHour; i <= lEndHour; i++) - [ma addObject:[NSNumber numberWithInt:i]]; - return ma; -} - -- (NSArray *)days { - // TODO: from startdate to enddate - NSMutableArray *ma; - NSCalendarDate *base, *stop, *current; - NSTimeZone *timeZone; - - timeZone = [[context activeUser] timeZone]; - base = [NSCalendarDate dateWithYear:[[self startDateYear] intValue] - month:[[self startDateMonth] intValue] - day:[[self startDateDay] intValue] - hour:12 minute:0 second:0 - timeZone: timeZone]; - stop = [NSCalendarDate dateWithYear:[[self endDateYear] intValue] - month:[[self endDateMonth] intValue] - day:[[self endDateDay] intValue] - hour:12 minute:0 second:0 - timeZone: timeZone]; - ma = [NSMutableArray arrayWithCapacity: 16]; - - current = base; - while ([current compare:stop] != NSOrderedDescending) - { - [current setTimeZone: timeZone]; - [ma addObject:current]; - - /* Note: remember the timezone behaviour of the method below! */ - current = [current dateByAddingYears:0 months:0 days:1]; - } - - return ma; -} - -- (NSArray *)durationSteps { - // TODO: make configurable - return [NSArray arrayWithObjects: - @"30", @"60", @"120", @"240", @"480", nil]; -} - -/* slots */ - -- (BOOL)isRangeGreen:(NGCalendarDateRange *)_range { - unsigned idx; - - idx = [self->blockedRanges indexOfFirstIntersectingDateRange:_range]; - if (idx != NSNotFound) { - [self debugWithFormat:@"blocked range:\n range: %@\n block: %@\nintersection:%@", - _range, - [self->blockedRanges objectAtIndex:idx], - [_range intersectionDateRange:[self->blockedRanges objectAtIndex:idx]]]; - } - - return idx == NSNotFound ? YES : NO; -} - -- (BOOL)isSlotRangeGreen:(NGCalendarDateRange *)_slotRange { - NGCalendarDateRange *aptRange; - NSCalendarDate *aptStartDate, *aptEndDate; - NSTimeZone *timeZone; - - if (_slotRange == nil) - return NO; - - /* calculate the interval requested by the user (can be larger) */ - - aptStartDate = [_slotRange startDate]; - // TODO: gives warning on MacOSX - aptEndDate = [[NSCalendarDate alloc] initWithTimeIntervalSince1970: - [aptStartDate timeIntervalSince1970] - + [self durationAsTimeInterval]]; - timeZone = [[context activeUser] timeZone]; - [aptStartDate setTimeZone: timeZone]; - [aptEndDate setTimeZone: timeZone]; - aptRange = [NGCalendarDateRange calendarDateRangeWithStartDate:aptStartDate - endDate:aptEndDate]; - [aptEndDate release]; aptEndDate = nil; - - return [self isRangeGreen:aptRange]; -} - -- (BOOL)isFirstHalfGreen { - /* currentday is the date, self->item the hour */ - NSCalendarDate *from, *to; - NGCalendarDateRange *range; - - from = [self->currentDay hour:[[self item] intValue] minute:0]; - to = [self->currentDay hour:[[self item] intValue] minute:30]; - range = [NGCalendarDateRange calendarDateRangeWithStartDate:from endDate:to]; - return [self isSlotRangeGreen:range]; -} -- (BOOL)isSecondHalfGreen { - /* currentday is the date, self->item the hour */ - NSCalendarDate *from, *to; - NGCalendarDateRange *range; - - from = [self->currentDay hour:[[self item] intValue] minute:30]; - to = [self->currentDay hour:[[self item] intValue] + 1 minute:0]; - range = [NGCalendarDateRange calendarDateRangeWithStartDate:from endDate:to]; - return [self isSlotRangeGreen:range]; -} - -- (BOOL)isFirstHalfBlocked { - return [self isFirstHalfGreen] ? NO : YES; -} -- (BOOL)isSecondHalfBlocked { - return [self isSecondHalfGreen] ? NO : YES; -} - -/* actions */ - -- (BOOL)shouldTakeValuesFromRequest:(WORequest *)_rq inContext:(WOContext*)_c{ - return YES; -} - -- (id)defaultAction { - NSCalendarDate *now; - - now = [NSCalendarDate date]; - - [self setDuration:@"120"]; /* 1 hour as default */ - [self setStartDate:[now hour:9 minute:0]]; - [self setEndDate:[now hour:18 minute:0]]; - - return self; -} - -- (id)proposalSearchAction { - NSArray *attendees, *uids, *fbos, *ranges; - unsigned i, count; - NSMutableArray *allInfos; - - [self logWithFormat:@"search from %@ to %@", - [self startDate], [self endDate]]; - - attendees = [self attendees]; - uids = [[self clientObject] uidsFromICalPersons:attendees]; - if ([uids count] == 0) { - [self logWithFormat:@"Note: no UIDs selected."]; - return self; - } - - fbos = [[self clientObject] lookupFreeBusyObjectsForUIDs:uids - inContext:[self context]]; - count = [fbos count]; - // wild guess at capacity - allInfos = [[[NSMutableArray alloc] initWithCapacity:count * 10] autorelease]; - - for (i = 0; i < count; i++) { - SOGoFreeBusyObject *fb; - NSArray *infos; - - fb = [fbos objectAtIndex:i]; - if (fb != (SOGoFreeBusyObject *)[NSNull null]) { - infos = [fb fetchFreeBusyInfosFrom:[self startDate] to:[self endDate]]; - [allInfos addObjectsFromArray:infos]; - } - } - [self debugWithFormat:@" processing: %d infos", [allInfos count]]; - ranges = [allInfos arrayByCreatingDateRangesFromObjectsWithStartDateKey: - @"startDate" - andEndDateKey:@"endDate"]; - ranges = [ranges arrayByCompactingContainedDateRanges]; - [self debugWithFormat:@" ranges: %@", ranges]; - - ASSIGNCOPY(self->blockedRanges, ranges); - - return self; -} - -/* URLs */ - -- (NSMutableDictionary *)currentQueryParameters { - if(!self->currentQueryParameters) { - self->currentQueryParameters = [[self queryParameters] mutableCopy]; - [self->currentQueryParameters setObject:[self duration] forKey:@"dur"]; - [self setICalPersons:[self resources] asQueryParameter:@"rs"]; - [self setICalPersons:[self participants] asQueryParameter:@"ps"]; - } - return self->currentQueryParameters; -} - -- (void)setICalPersons:(NSArray *)_ps asQueryParameter:(NSString *)_qp { - NSMutableString *s; - unsigned i, count; - - s = [[NSMutableString alloc] init]; - count = [_ps count]; - for(i = 0; i < count; i++) { - iCalPerson *p = [_ps objectAtIndex:i]; - [s appendString:[p rfc822Email]]; - if(i != (count - 1)) - [s appendString:@","]; - } - [[self currentQueryParameters] setObject:s forKey:_qp]; - [s release]; -} - -- (NSDictionary *)currentHourQueryParametersForFirstHalf:(BOOL)_first { - NSMutableDictionary *qp; - NSString *hmString; - NSCalendarDate *date; - unsigned minute; - - minute = _first ? 0 : 30; - qp = [self currentQueryParameters]; - - date = [self currentDay]; - hmString = [NSString stringWithFormat:@"%02d%02d", - [item intValue], minute]; - [self setSelectedDateQueryParameter:date inDictionary:qp]; - [qp setObject:hmString forKey:@"hm"]; - return qp; -} - -- (NSDictionary *)currentFirstHalfQueryParameters { - return [self currentHourQueryParametersForFirstHalf:YES]; -} - -- (NSDictionary *)currentSecondHalfQueryParameters { - return [self currentHourQueryParametersForFirstHalf:NO]; -} - -@end /* UIxAppointmentProposal */ diff --git a/UI/Scheduler/UIxTaskProposal.m b/UI/Scheduler/UIxTaskProposal.m deleted file mode 100644 index c472684b8..000000000 --- a/UI/Scheduler/UIxTaskProposal.m +++ /dev/null @@ -1,515 +0,0 @@ -/* - Copyright (C) 2004 SKYRIX Software AG - - This file is part of OpenGroupware.org. - - OGo is free software; you can redistribute it and/or modify it under - the terms of the GNU Lesser General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - OGo is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public - License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with OGo; see the file COPYING. If not, write to the - Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. -*/ -// $Id: UIxTaskEditor.m 181 2004-08-11 15:13:25Z helge $ - -#import -#import -#import - -#import -#import -#import - -#import -#import -#import - -@interface UIxTaskProposal : UIxComponent -{ - id item; - id currentDay; - - /* individual values */ - id startDateHour; - id startDateMinute; - id endDateHour; - id endDateMinute; - - id startDateDay; - id startDateMonth; - id startDateYear; - id endDateDay; - id endDateMonth; - id endDateYear; - - NSArray *participants; /* array of iCalPerson's */ - NSArray *resources; /* array of iCalPerson's */ - id duration; - - NSArray *blockedRanges; - NSMutableDictionary *currentQueryParameters; -} - -- (NSMutableDictionary *)currentQueryParameters; -- (NSDictionary *)currentHourQueryParametersForFirstHalf:(BOOL)_first; - -- (void)setICalPersons:(NSArray *)_ps asQueryParameter:(NSString *)_qp; -@end - -@implementation UIxTaskProposal - -- (void)dealloc { - [self->blockedRanges release]; - - [self->startDateHour release]; - [self->startDateMinute release]; - [self->startDateDay release]; - [self->startDateMonth release]; - [self->startDateYear release]; - - [self->endDateHour release]; - [self->endDateMinute release]; - [self->endDateDay release]; - [self->endDateMonth release]; - [self->endDateYear release]; - [self->duration release]; - - [self->participants release]; - [self->resources release]; - - [self->currentQueryParameters release]; - [super dealloc]; -} - -/* notifications */ - -- (void)sleep { - [self->currentDay release]; self->currentDay = nil; - [self->item release]; self->item = nil; - [super sleep]; -} - -/* accessors */ - -- (void)setItem:(id)_item { - ASSIGN(self->item, _item); -} -- (id)item { - return self->item; -} - -- (void)setStartDateHour:(id)_startDateHour { - ASSIGN(self->startDateHour, _startDateHour); -} -- (id)startDateHour { - return self->startDateHour; -} -- (void)setStartDateMinute:(id)_startDateMinute { - ASSIGN(self->startDateMinute, _startDateMinute); -} -- (id)startDateMinute { - return self->startDateMinute; -} -- (void)setStartDateDay:(id)_startDateDay { - ASSIGN(self->startDateDay, _startDateDay); -} -- (id)startDateDay { - return self->startDateDay; -} -- (void)setStartDateMonth:(id)_startDateMonth { - ASSIGN(self->startDateMonth, _startDateMonth); -} -- (id)startDateMonth { - return self->startDateMonth; -} -- (void)setStartDateYear:(id)_startDateYear { - ASSIGN(self->startDateYear, _startDateYear); -} -- (id)startDateYear { - return self->startDateYear; -} -- (void)setEndDateHour:(id)_endDateHour { - ASSIGN(self->endDateHour, _endDateHour); -} -- (id)endDateHour { - return self->endDateHour; -} -- (void)setEndDateMinute:(id)_endDateMinute { - ASSIGN(self->endDateMinute, _endDateMinute); -} -- (id)endDateMinute { - return self->endDateMinute; -} -- (void)setEndDateDay:(id)_endDateDay { - ASSIGN(self->endDateDay, _endDateDay); -} -- (id)endDateDay { - return self->endDateDay; -} -- (void)setEndDateMonth:(id)_endDateMonth { - ASSIGN(self->endDateMonth, _endDateMonth); -} -- (id)endDateMonth { - return self->endDateMonth; -} -- (void)setEndDateYear:(id)_endDateYear { - ASSIGN(self->endDateYear, _endDateYear); -} -- (id)endDateYear { - return self->endDateYear; -} - -- (void)setStartDate:(NSCalendarDate *)_date { - [self setStartDateHour:[NSNumber numberWithInt:[_date hourOfDay]]]; - [self setStartDateMinute:[NSNumber numberWithInt:[_date minuteOfHour]]]; - [self setStartDateDay:[NSNumber numberWithInt:[_date dayOfMonth]]]; - [self setStartDateMonth:[NSNumber numberWithInt:[_date monthOfYear]]]; - [self setStartDateYear:[NSNumber numberWithInt:[_date yearOfCommonEra]]]; -} - -- (NSCalendarDate *) startDate -{ - NSTimeZone *timeZone; - - timeZone = [[context activeUser] timeZone]; - - return [NSCalendarDate dateWithYear:[[self startDateYear] intValue] - month:[[self startDateMonth] intValue] - day:[[self startDateDay] intValue] - hour:[[self startDateHour] intValue] - minute:[[self startDateMinute] intValue] - second:0 - timeZone: timeZone]; -} - -- (void) setEndDate: (NSCalendarDate *) _date -{ - [self setEndDateHour:[NSNumber numberWithInt:[_date hourOfDay]]]; - [self setEndDateMinute:[NSNumber numberWithInt:[_date minuteOfHour]]]; - [self setEndDateDay:[NSNumber numberWithInt:[_date dayOfMonth]]]; - [self setEndDateMonth:[NSNumber numberWithInt:[_date monthOfYear]]]; - [self setEndDateYear:[NSNumber numberWithInt:[_date yearOfCommonEra]]]; -} - -- (NSCalendarDate *) endDate -{ - NSTimeZone *timeZone; - - timeZone = [[context activeUser] timeZone]; - - return [NSCalendarDate dateWithYear:[[self endDateYear] intValue] - month:[[self endDateMonth] intValue] - day:[[self endDateDay] intValue] - hour:[[self endDateHour] intValue] - minute:[[self endDateMinute] intValue] - second:59 - timeZone: timeZone]; -} - -- (void)setDuration:(id)_duration { - ASSIGN(self->duration, _duration); -} -- (id)duration { - return self->duration; -} -- (int)durationInMinutes { - return [[self duration] intValue]; -} -- (NSTimeInterval)durationAsTimeInterval { - return [self durationInMinutes] * 60; -} - -- (NSString *)itemDurationText { - // TODO: use a formatter - // TODO: localize - switch ([[self item] intValue]) { - case 30: return @"30 minutes"; - case 60: return @"1 hour"; - case 120: return @"2 hours"; - case 240: return @"4 hours"; - case 480: return @"8 hours"; - default: - return [NSString stringWithFormat:@"%@ minutes", [self item]]; - } -} - -- (void)setParticipants:(NSArray *)_parts { - ASSIGN(self->participants, _parts); -} -- (NSArray *)participants { - return self->participants; -} -- (void)setResources:(NSArray *)_res { - ASSIGN(self->resources, _res); -} -- (NSArray *)resources { - return self->resources; -} - -- (NSArray *)attendees { - NSArray *a, *b; - - a = [self participants]; - b = [self resources]; - if ([b count] == 0) return a; - if ([a count] == 0) return b; - return [a arrayByAddingObjectsFromArray:b]; -} - -- (void)setCurrentDay:(id)_day { - ASSIGN(self->currentDay, _day); -} -- (id)currentDay { - return self->currentDay; -} - -- (NSArray *)hours { - // TODO: from 'earliest start' to 'latest endtime' - unsigned lStartHour = 9, lEndHour = 17, i; - NSMutableArray *ma; - - lStartHour = [[self startDateHour] intValue]; - lEndHour = [[self endDateHour] intValue]; - if (lStartHour < 1) lStartHour = 1; - if (lEndHour < lStartHour) lEndHour = lStartHour + 1; - - ma = [NSMutableArray arrayWithCapacity:lEndHour - lStartHour + 2]; - for (i = lStartHour; i <= lEndHour; i++) - [ma addObject:[NSNumber numberWithInt:i]]; - return ma; -} - -- (NSArray *) days -{ - // TODO: from startdate to enddate - NSMutableArray *ma; - NSCalendarDate *base, *stop, *current; - NSTimeZone *timeZone; - - timeZone = [[context activeUser] timeZone]; - base = [NSCalendarDate dateWithYear: [[self startDateYear] intValue] - month: [[self startDateMonth] intValue] - day: [[self startDateDay] intValue] - hour: 12 minute: 0 second: 0 - timeZone: timeZone]; - stop = [NSCalendarDate dateWithYear: [[self endDateYear] intValue] - month: [[self endDateMonth] intValue] - day: [[self endDateDay] intValue] - hour: 12 minute: 0 second: 0 - timeZone: timeZone]; - - ma = [NSMutableArray arrayWithCapacity:16]; - - current = base; - while ([current compare:stop] != NSOrderedDescending) { - [current setTimeZone: timeZone]; - [ma addObject:current]; - - /* Note: remember the timezone behaviour of the method below! */ - current = [current dateByAddingYears:0 months:0 days:1]; - } - - return ma; -} - -- (NSArray *)durationSteps { - // TODO: make configurable - return [NSArray arrayWithObjects: - @"30", @"60", @"120", @"240", @"480", nil]; -} - -/* slots */ - -- (BOOL)isRangeGreen:(NGCalendarDateRange *)_range { - unsigned idx; - - idx = [self->blockedRanges indexOfFirstIntersectingDateRange:_range]; - if (idx != NSNotFound) { - [self debugWithFormat:@"blocked range:\n range: %@\n block: %@\nintersection:%@", - _range, - [self->blockedRanges objectAtIndex:idx], - [_range intersectionDateRange:[self->blockedRanges objectAtIndex:idx]]]; - } - - return idx == NSNotFound ? YES : NO; -} - -- (BOOL)isSlotRangeGreen: (NGCalendarDateRange *) _slotRange -{ - NGCalendarDateRange *aptRange; - NSCalendarDate *aptStartDate, *aptEndDate; - NSTimeZone *timeZone; - - if (_slotRange == nil) - return NO; - - timeZone = [[context activeUser] timeZone]; - /* calculate the interval requested by the user (can be larger) */ - - aptStartDate = [_slotRange startDate]; - // TODO: gives warning on MacOSX - aptEndDate - = [[NSCalendarDate alloc] - initWithTimeIntervalSince1970: ([aptStartDate timeIntervalSince1970] - + [self durationAsTimeInterval])]; - [aptStartDate setTimeZone: timeZone]; - [aptEndDate setTimeZone: timeZone]; - aptRange = [NGCalendarDateRange calendarDateRangeWithStartDate: aptStartDate - endDate: aptEndDate]; - [aptEndDate release]; - aptEndDate = nil; - - return [self isRangeGreen: aptRange]; -} - -- (BOOL)isFirstHalfGreen { - /* currentday is the date, self->item the hour */ - NSCalendarDate *from, *to; - NGCalendarDateRange *range; - - from = [self->currentDay hour:[[self item] intValue] minute:0]; - to = [self->currentDay hour:[[self item] intValue] minute:30]; - range = [NGCalendarDateRange calendarDateRangeWithStartDate:from endDate:to]; - return [self isSlotRangeGreen:range]; -} -- (BOOL)isSecondHalfGreen { - /* currentday is the date, self->item the hour */ - NSCalendarDate *from, *to; - NGCalendarDateRange *range; - - from = [self->currentDay hour:[[self item] intValue] minute:30]; - to = [self->currentDay hour:[[self item] intValue] + 1 minute:0]; - range = [NGCalendarDateRange calendarDateRangeWithStartDate:from endDate:to]; - return [self isSlotRangeGreen:range]; -} - -- (BOOL)isFirstHalfBlocked { - return [self isFirstHalfGreen] ? NO : YES; -} -- (BOOL)isSecondHalfBlocked { - return [self isSecondHalfGreen] ? NO : YES; -} - -/* actions */ - -- (BOOL)shouldTakeValuesFromRequest:(WORequest *)_rq inContext:(WOContext*)_c{ - return YES; -} - -- (id)defaultAction { - NSCalendarDate *now; - - now = [NSCalendarDate date]; - - [self setDuration:@"120"]; /* 1 hour as default */ - [self setStartDate:[now hour:9 minute:0]]; - [self setEndDate:[now hour:18 minute:0]]; - - return self; -} - -- (id)proposalSearchAction { - NSArray *attendees, *uids, *fbos, *ranges; - unsigned i, count; - NSMutableArray *allInfos; - - [self logWithFormat:@"search from %@ to %@", - [self startDate], [self endDate]]; - - attendees = [self attendees]; - uids = [[self clientObject] uidsFromICalPersons:attendees]; - if ([uids count] == 0) { - [self logWithFormat:@"Note: no UIDs selected."]; - return self; - } - - fbos = [[self clientObject] lookupFreeBusyObjectsForUIDs:uids - inContext:[self context]]; - count = [fbos count]; - // wild guess at capacity - allInfos = [[[NSMutableArray alloc] initWithCapacity:count * 10] autorelease]; - - for (i = 0; i < count; i++) { - SOGoFreeBusyObject *fb; - NSArray *infos; - - fb = [fbos objectAtIndex:i]; - if (fb != (SOGoFreeBusyObject *)[NSNull null]) { - infos = [fb fetchFreeBusyInfosFrom:[self startDate] to:[self endDate]]; - [allInfos addObjectsFromArray:infos]; - } - } - [self debugWithFormat:@" processing: %d infos", [allInfos count]]; - ranges = [allInfos arrayByCreatingDateRangesFromObjectsWithStartDateKey: - @"startDate" - andEndDateKey:@"endDate"]; - ranges = [ranges arrayByCompactingContainedDateRanges]; - [self debugWithFormat:@" ranges: %@", ranges]; - - ASSIGNCOPY(self->blockedRanges, ranges); - - return self; -} - -/* URLs */ - -- (NSMutableDictionary *)currentQueryParameters { - if(!self->currentQueryParameters) { - self->currentQueryParameters = [[self queryParameters] mutableCopy]; - [self->currentQueryParameters setObject:[self duration] forKey:@"dur"]; - [self setICalPersons:[self resources] asQueryParameter:@"rs"]; - [self setICalPersons:[self participants] asQueryParameter:@"ps"]; - } - return self->currentQueryParameters; -} - -- (void)setICalPersons:(NSArray *)_ps asQueryParameter:(NSString *)_qp { - NSMutableString *s; - unsigned i, count; - - s = [[NSMutableString alloc] init]; - count = [_ps count]; - for(i = 0; i < count; i++) { - iCalPerson *p = [_ps objectAtIndex:i]; - [s appendString:[p rfc822Email]]; - if(i != (count - 1)) - [s appendString:@","]; - } - [[self currentQueryParameters] setObject:s forKey:_qp]; - [s release]; -} - -- (NSDictionary *)currentHourQueryParametersForFirstHalf:(BOOL)_first { - NSMutableDictionary *qp; - NSString *hmString; - NSCalendarDate *date; - unsigned minute; - - minute = _first ? 0 : 30; - qp = [self currentQueryParameters]; - - date = [self currentDay]; - hmString = [NSString stringWithFormat:@"%02d%02d", - [item intValue], minute]; - [self setSelectedDateQueryParameter:date inDictionary:qp]; - [qp setObject:hmString forKey:@"hm"]; - return qp; -} - -- (NSDictionary *)currentFirstHalfQueryParameters { - return [self currentHourQueryParametersForFirstHalf:YES]; -} - -- (NSDictionary *)currentSecondHalfQueryParameters { - return [self currentHourQueryParametersForFirstHalf:NO]; -} - -@end /* UIxTaskProposal */ diff --git a/UI/Scheduler/product.plist b/UI/Scheduler/product.plist index 9f883e69b..603b5569f 100644 --- a/UI/Scheduler/product.plist +++ b/UI/Scheduler/product.plist @@ -90,15 +90,6 @@ pageName = "UIxCalView"; actionName = "redirectForUIDs"; }; - // proposal = { - // protectedBy = "View"; - // pageName = "UIxAppointmentProposal"; - // }; - // proposalSearch = { - // protectedBy = "View"; - // pageName = "UIxAppointmentProposal"; - // actionName = "proposalSearch"; - // }; userRights = { protectedBy = "ReadAcls"; pageName = "UIxCalUserRightsEditor"; diff --git a/UI/WebServerResources/SchedulerUI.js b/UI/WebServerResources/SchedulerUI.js index 8be5f992d..39e121924 100644 --- a/UI/WebServerResources/SchedulerUI.js +++ b/UI/WebServerResources/SchedulerUI.js @@ -1270,7 +1270,7 @@ function refreshEvents() { var titleSearch; var value = search["value"]; if (value && value.length) - titleSearch = "&search=" + value; + titleSearch = "&search=" + escape(value.utf8encode()); else titleSearch = "";