See ChangeLogs
Monotone-Parent: e2ba584b1367987b411373efc53338c1daf189da Monotone-Revision: ea7589320f5747a3bd1bbec33e1bd8776e4041db Monotone-Author: flachapelle@inverse.ca Monotone-Date: 2009-04-21T14:34:22 Monotone-Branch: ca.inverse.sogomaint-2.0.2
parent
3b9d0b83cf
commit
fa7408ebc1
13
ChangeLog
13
ChangeLog
|
@ -1,3 +1,16 @@
|
|||
2009-04-21 Francis Lachapelle <flachapelle@inverse.ca>
|
||||
|
||||
* UI/Scheduler/UIxTaskEditor.m ([UIxTaskEditor
|
||||
-takeValuesFromRequest:inContext:]): removes any alarm if the
|
||||
vTodo doesn't have a due date.
|
||||
|
||||
* UI/Scheduler/UIxComponentEditor.m ([UIxComponentEditor
|
||||
-_loadAlarms]): new method to extract the first alarm of the component.
|
||||
|
||||
* SoObjects/Appointments/iCalEvent+SOGo.m ([iCalEvent
|
||||
-quickRecord]): added support for an event's alarm. The database
|
||||
field "c_nextalarm" must first be added to all tables.
|
||||
|
||||
2009-04-13 Ludovic Marcotte <lmarcotte@inverse.ca>
|
||||
|
||||
* SoObjects/SOGo/LDAPSource.m: cleaned up and
|
||||
|
|
|
@ -1,3 +1,11 @@
|
|||
2009-04-21 Francis Lachapelle <flachapelle@inverse.ca>
|
||||
|
||||
* iCalTrigger.m ([iCalTrigger -setRelationType:]): new method to
|
||||
set the "related" attribute of an alarm trigger.
|
||||
|
||||
* NSString+NGCards.m ([NSString -durationAsTimeInterval]): added
|
||||
support of negative durations.
|
||||
|
||||
2009-03-24 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* iCalWeeklyRecurrenceCalculator.m
|
||||
|
|
|
@ -158,20 +158,33 @@ static NSString *commaSeparator = nil;
|
|||
*/
|
||||
unsigned i, len;
|
||||
NSTimeInterval ti;
|
||||
BOOL isTime;
|
||||
BOOL isNegative, isTime;
|
||||
int val;
|
||||
unichar c;
|
||||
|
||||
ti = 0.0;
|
||||
i = 0;
|
||||
|
||||
if ([self hasPrefix:@"P"])
|
||||
c = [self characterAtIndex: i];
|
||||
if (c == '-')
|
||||
{
|
||||
isNegative = YES;
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
isNegative = NO;
|
||||
}
|
||||
|
||||
c = [self characterAtIndex: i];
|
||||
if (c == 'P')
|
||||
{
|
||||
val = 0;
|
||||
|
||||
len = [self length];
|
||||
isTime = NO;
|
||||
|
||||
for (i = 1; i < len; i++)
|
||||
for (i++; i < len; i++)
|
||||
{
|
||||
c = [self characterAtIndex: i];
|
||||
if (c == 't' || c == 'T')
|
||||
|
@ -212,6 +225,9 @@ static NSString *commaSeparator = nil;
|
|||
else
|
||||
NSLog(@"Cannot parse iCal duration value: '%@'", self);
|
||||
|
||||
if (isNegative)
|
||||
ti = -ti;
|
||||
|
||||
return ti;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,9 +32,11 @@
|
|||
|
||||
/* accessors */
|
||||
|
||||
- (void) setTrigger: (iCalTrigger *) _value;
|
||||
- (iCalTrigger *) trigger;
|
||||
- (iCalAttachment *) attach;
|
||||
- (NSString *) comment;
|
||||
- (void) setAction: (NSString *) _value;
|
||||
- (NSString *) action;
|
||||
- (void) setRecurrenceRule: (NSString *) _recurrenceRule;
|
||||
- (NSString *) recurrenceRule;
|
||||
|
|
|
@ -26,12 +26,15 @@
|
|||
|
||||
@interface iCalTrigger : CardElement
|
||||
|
||||
- (void) setValue: (NSString *) aValue;
|
||||
- (void) setValue: (NSString *) theValue;
|
||||
- (NSString *) value;
|
||||
|
||||
- (void) setValueType: (NSString *) aType;
|
||||
- (void) setValueType: (NSString *) theType;
|
||||
- (NSString *) valueType;
|
||||
|
||||
- (void) setRelationType: (NSString *) theRelationType;
|
||||
- (NSString *) relationType;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* __NGCards_iCalTrigger_H__ */
|
||||
|
|
|
@ -27,9 +27,9 @@
|
|||
|
||||
/* accessors */
|
||||
|
||||
- (void) setValue: (NSString *) _value
|
||||
- (void) setValue: (NSString *) theValue
|
||||
{
|
||||
[self setValue: 0 to: _value];
|
||||
[self setValue: 0 to: theValue];
|
||||
}
|
||||
|
||||
- (NSString *) value
|
||||
|
@ -37,14 +37,24 @@
|
|||
return [self value: 0];
|
||||
}
|
||||
|
||||
- (void) setValueType: (NSString *) _value
|
||||
- (void) setValueType: (NSString *) theValue
|
||||
{
|
||||
[self setValue: 0 ofAttribute: @"type" to: _value];
|
||||
[self setValue: 0 ofAttribute: @"value" to: theValue];
|
||||
}
|
||||
|
||||
- (NSString *) valueType
|
||||
{
|
||||
return [self value: 0 ofAttribute: @"type"];
|
||||
return [self value: 0 ofAttribute: @"value"];
|
||||
}
|
||||
|
||||
- (void) setRelationType: (NSString *) theRelationType
|
||||
{
|
||||
[self setValue: 0 ofAttribute: @"related" to: theRelationType];
|
||||
}
|
||||
|
||||
- (NSString *) relationType
|
||||
{
|
||||
return [self value: 0 ofAttribute: @"related"];
|
||||
}
|
||||
|
||||
@end /* iCalTrigger */
|
||||
|
|
|
@ -29,8 +29,11 @@
|
|||
#import <NGExtensions/NSNull+misc.h>
|
||||
#import <NGExtensions/NSObject+Logs.h>
|
||||
|
||||
#import <NGCards/iCalAlarm.h>
|
||||
#import <NGCards/iCalEvent.h>
|
||||
#import <NGCards/iCalPerson.h>
|
||||
#import <NGCards/iCalTrigger.h>
|
||||
#import <NGCards/NSString+NGCards.h>
|
||||
|
||||
#import "iCalRepeatableEntityObject+SOGo.h"
|
||||
|
||||
|
@ -59,7 +62,7 @@
|
|||
- (NSMutableDictionary *) quickRecord
|
||||
{
|
||||
NSMutableDictionary *row;
|
||||
NSCalendarDate *startDate, *endDate;
|
||||
NSCalendarDate *startDate, *endDate, *nextAlarmDate;
|
||||
NSArray *attendees;
|
||||
NSString *uid, *title, *location, *status;
|
||||
NSNumber *sequence;
|
||||
|
@ -74,6 +77,7 @@
|
|||
|
||||
startDate = [self startDate];
|
||||
endDate = [self endDate];
|
||||
nextAlarmDate = nil;
|
||||
uid = [self uid];
|
||||
title = [self summary];
|
||||
if (![title isNotNull])
|
||||
|
@ -199,6 +203,73 @@
|
|||
[row setObject:partstates forKey: @"c_partstates"];
|
||||
[partstates release];
|
||||
|
||||
if ([self hasAlarms])
|
||||
{
|
||||
// We currently have the following limitations for alarms:
|
||||
// - only the first alarm is considered;
|
||||
// - the alarm's action must be of type DISPLAY;
|
||||
// - the alarm's trigger value type must be DURATION.
|
||||
|
||||
iCalAlarm *anAlarm;
|
||||
iCalTrigger *aTrigger;
|
||||
NSCalendarDate *relationDate;
|
||||
NSString *relation;
|
||||
NSTimeInterval anInterval;
|
||||
|
||||
anAlarm = [[self alarms] objectAtIndex: 0];
|
||||
aTrigger = [anAlarm trigger];
|
||||
relation = [aTrigger relationType];
|
||||
anInterval = [[aTrigger value] durationAsTimeInterval];
|
||||
|
||||
if ([[anAlarm action] caseInsensitiveCompare: @"DISPLAY"] == NSOrderedSame &&
|
||||
[[aTrigger valueType] caseInsensitiveCompare: @"DURATION"] == NSOrderedSame)
|
||||
{
|
||||
if ([self isRecurrent])
|
||||
{
|
||||
if ([self isStillRelevant])
|
||||
{
|
||||
NSArray *occurrences;
|
||||
NSCalendarDate *now, *later;
|
||||
NGCalendarDateRange *range;
|
||||
|
||||
// We only compute the next occurrence of the repeating event
|
||||
// for the next 48 hours
|
||||
now = [NSCalendarDate calendarDate];
|
||||
later = [now addTimeInterval: (60*60*48)];
|
||||
range = [NGCalendarDateRange calendarDateRangeWithStartDate: now
|
||||
endDate: later];
|
||||
occurrences = [self recurrenceRangesWithinCalendarDateRange: range];
|
||||
if ([occurrences count] > 0)
|
||||
{
|
||||
range = [occurrences objectAtIndex: 0];
|
||||
if ([relation caseInsensitiveCompare: @"END"] == NSOrderedSame)
|
||||
relationDate = [range endDate];
|
||||
else
|
||||
relationDate = [range startDate];
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Event is not reccurent
|
||||
if ([relation caseInsensitiveCompare: @"END"] == NSOrderedSame)
|
||||
relationDate = endDate;
|
||||
else
|
||||
relationDate = startDate;
|
||||
}
|
||||
|
||||
// Compute the next alarm date with respect to the reference date
|
||||
if ([relationDate isNotNull])
|
||||
nextAlarmDate = [relationDate addTimeInterval: anInterval];
|
||||
}
|
||||
}
|
||||
if ([nextAlarmDate isNotNull])
|
||||
[row setObject: [NSNumber numberWithInt: [nextAlarmDate timeIntervalSince1970]]
|
||||
forKey: @"c_nextalarm"];
|
||||
else
|
||||
[row setObject: [NSNumber numberWithInt: 0] forKey: @"c_nextalarm"];
|
||||
|
||||
|
||||
return row;
|
||||
}
|
||||
|
||||
|
|
|
@ -375,6 +375,14 @@
|
|||
"reminder_1_WEEK_BEFORE" = "1 week van tevoren";
|
||||
"reminder_CUSTOM" = "aangepast...";
|
||||
|
||||
"reminder_MINUTES" = "minutes";
|
||||
"reminder_HOURS" = "hours";
|
||||
"reminder_DAYS" = "days";
|
||||
"reminder_BEFORE" = "before";
|
||||
"reminder_AFTER" = "after";
|
||||
"reminder_START" = "the event starts";
|
||||
"reminder_END" = "the event ends";
|
||||
|
||||
"zoom_400" = "400%";
|
||||
"zoom_200" = "200%";
|
||||
"zoom_100" = "100%";
|
||||
|
|
|
@ -392,6 +392,14 @@
|
|||
"reminder_1_WEEK_BEFORE" = "1 week before";
|
||||
"reminder_CUSTOM" = "Custom...";
|
||||
|
||||
"reminder_MINUTES" = "minutes";
|
||||
"reminder_HOURS" = "hours";
|
||||
"reminder_DAYS" = "days";
|
||||
"reminder_BEFORE" = "before";
|
||||
"reminder_AFTER" = "after";
|
||||
"reminder_START" = "the event starts";
|
||||
"reminder_END" = "the event ends";
|
||||
|
||||
"zoom_400" = "400%";
|
||||
"zoom_200" = "200%";
|
||||
"zoom_100" = "100%";
|
||||
|
|
|
@ -390,6 +390,14 @@
|
|||
"reminder_1_WEEK_BEFORE" = "1 semaine avant";
|
||||
"reminder_CUSTOM" = "Personnaliser...";
|
||||
|
||||
"reminder_MINUTES" = "minutes";
|
||||
"reminder_HOURS" = "hours";
|
||||
"reminder_DAYS" = "days";
|
||||
"reminder_BEFORE" = "before";
|
||||
"reminder_AFTER" = "after";
|
||||
"reminder_START" = "the event starts";
|
||||
"reminder_END" = "the event ends";
|
||||
|
||||
"zoom_400" = "400%";
|
||||
"zoom_200" = "200%";
|
||||
"zoom_100" = "100%";
|
||||
|
|
|
@ -35,14 +35,15 @@ SchedulerUI_OBJC_FILES = \
|
|||
UIxComponentEditor.m \
|
||||
UIxCalendarSelector.m \
|
||||
UIxAppointmentEditor.m \
|
||||
UIxTaskEditor.m \
|
||||
UIxTaskEditor.m \
|
||||
UIxCalDateLabel.m \
|
||||
UIxDatePicker.m \
|
||||
UIxTimeDateControl.m \
|
||||
UIxCalParticipationStatusView.m \
|
||||
UIxCalMonthOverview.m \
|
||||
UIxCalMonthViewOld.m \
|
||||
UIxRecurrenceEditor.m \
|
||||
UIxCalMonthOverview.m \
|
||||
UIxCalMonthViewOld.m \
|
||||
UIxRecurrenceEditor.m \
|
||||
UIxReminderEditor.m \
|
||||
UIxOccurenceDialog.m
|
||||
|
||||
SchedulerUI_RESOURCE_FILES += \
|
||||
|
|
|
@ -389,6 +389,14 @@
|
|||
"reminder_1_WEEK_BEFORE" = "1 Woche vor";
|
||||
"reminder_CUSTOM" = "Benutzerdefiniert...";
|
||||
|
||||
"reminder_MINUTES" = "minutes";
|
||||
"reminder_HOURS" = "hours";
|
||||
"reminder_DAYS" = "days";
|
||||
"reminder_BEFORE" = "before";
|
||||
"reminder_AFTER" = "after";
|
||||
"reminder_START" = "the event starts";
|
||||
"reminder_END" = "the event ends";
|
||||
|
||||
"zoom_400" = "400%";
|
||||
"zoom_200" = "200%";
|
||||
"zoom_100" = "100%";
|
||||
|
|
|
@ -392,6 +392,14 @@
|
|||
"reminder_1_WEEK_BEFORE" = "1 settimana prima";
|
||||
"reminder_CUSTOM" = "Personalizza...";
|
||||
|
||||
"reminder_MINUTES" = "minutes";
|
||||
"reminder_HOURS" = "hours";
|
||||
"reminder_DAYS" = "days";
|
||||
"reminder_BEFORE" = "before";
|
||||
"reminder_AFTER" = "after";
|
||||
"reminder_START" = "the event starts";
|
||||
"reminder_END" = "the event ends";
|
||||
|
||||
"zoom_400" = "400%";
|
||||
"zoom_200" = "200%";
|
||||
"zoom_100" = "100%";
|
||||
|
|
|
@ -396,6 +396,14 @@
|
|||
"reminder_1_WEEK_BEFORE" = "1 semana antes";
|
||||
"reminder_CUSTOM" = "personalizado...";
|
||||
|
||||
"reminder_MINUTES" = "minutes";
|
||||
"reminder_HOURS" = "hours";
|
||||
"reminder_DAYS" = "days";
|
||||
"reminder_BEFORE" = "before";
|
||||
"reminder_AFTER" = "after";
|
||||
"reminder_START" = "the event starts";
|
||||
"reminder_END" = "the event ends";
|
||||
|
||||
"zoom_400" = "400%";
|
||||
"zoom_200" = "200%";
|
||||
"zoom_100" = "100%";
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* UIxComponentEditor.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2006-2008 Inverse inc.
|
||||
* Copyright (C) 2006-2009 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -67,10 +67,15 @@
|
|||
NSString *attendeesEmails;
|
||||
NSString *attendeesStates;
|
||||
|
||||
NSString *repeat;
|
||||
NSString *reminder;
|
||||
NSString *reminderQuantity;
|
||||
NSString *reminderUnit;
|
||||
NSString *reminderRelation;
|
||||
NSString *reminderReference;
|
||||
|
||||
/* ugly */
|
||||
NSString *repeat;
|
||||
|
||||
NSString *repeatType;
|
||||
NSString *repeat1;
|
||||
NSString *repeat2;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* UIxComponentEditor.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2006-2008 Inverse inc.
|
||||
* Copyright (C) 2006-2009 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -30,9 +30,11 @@
|
|||
#import <Foundation/NSUserDefaults.h>
|
||||
#import <Foundation/NSURL.h>
|
||||
|
||||
#import <NGCards/iCalAlarm.h>
|
||||
#import <NGCards/iCalPerson.h>
|
||||
#import <NGCards/iCalRepeatableEntityObject.h>
|
||||
#import <NGCards/iCalRecurrenceRule.h>
|
||||
#import <NGCards/iCalTrigger.h>
|
||||
#import <NGCards/NSString+NGCards.h>
|
||||
#import <NGCards/NSCalendarDate+NGCards.h>
|
||||
#import <NGObjWeb/SoSecurityManager.h>
|
||||
|
@ -61,6 +63,9 @@
|
|||
#import "UIxComponentEditor.h"
|
||||
#import "UIxDatePicker.h"
|
||||
|
||||
static NSArray *reminderItems = nil;
|
||||
static NSArray *reminderValues = nil;
|
||||
|
||||
#define iREPEAT(X) \
|
||||
- (NSString *) repeat##X; \
|
||||
- (void) setRepeat##X: (NSString *) theValue
|
||||
|
@ -94,6 +99,52 @@ iRANGE(2);
|
|||
|
||||
@implementation UIxComponentEditor
|
||||
|
||||
+ (void) initialize
|
||||
{
|
||||
if (!reminderItems && !reminderValues)
|
||||
{
|
||||
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];
|
||||
reminderValues = [NSArray arrayWithObjects:
|
||||
@"-PT5M",
|
||||
@"-PT10M",
|
||||
@"-PT15M",
|
||||
@"-PT30M",
|
||||
@"-PT45M",
|
||||
@"",
|
||||
@"-PT1H",
|
||||
@"-PT2H",
|
||||
@"-PT5H",
|
||||
@"-PT15H",
|
||||
@"",
|
||||
@"-P1D",
|
||||
@"-P2D",
|
||||
@"-P1W",
|
||||
@"",
|
||||
@"",
|
||||
nil];
|
||||
|
||||
[reminderItems retain];
|
||||
[reminderValues retain];
|
||||
}
|
||||
}
|
||||
|
||||
- (id) init
|
||||
{
|
||||
UIxDatePicker *datePicker;
|
||||
|
@ -120,6 +171,10 @@ iRANGE(2);
|
|||
calendarList = nil;
|
||||
repeat = nil;
|
||||
reminder = nil;
|
||||
reminderQuantity = nil;
|
||||
reminderUnit = nil;
|
||||
reminderRelation = nil;
|
||||
reminderReference = nil;
|
||||
repeatType = nil;
|
||||
repeat1 = nil;
|
||||
repeat2 = nil;
|
||||
|
@ -155,9 +210,13 @@ iRANGE(2);
|
|||
[attendeesStates release];
|
||||
[calendarList release];
|
||||
|
||||
[repeat release];
|
||||
[reminder release];
|
||||
[reminderQuantity release];
|
||||
[reminderUnit release];
|
||||
[reminderRelation release];
|
||||
[reminderReference release];
|
||||
|
||||
[repeat release];
|
||||
[repeatType release];
|
||||
[repeat1 release];
|
||||
[repeat2 release];
|
||||
|
@ -372,6 +431,90 @@ iRANGE(2);
|
|||
}
|
||||
}
|
||||
|
||||
- (void) _loadAlarms
|
||||
{
|
||||
if ([component hasAlarms])
|
||||
{
|
||||
// We currently have the following limitations for alarms:
|
||||
// - only the first alarm is considered;
|
||||
// - the alarm's action must be of type DISPLAY;
|
||||
// - the alarm's trigger value type must be DURATION.
|
||||
|
||||
iCalAlarm *anAlarm;
|
||||
iCalTrigger *aTrigger;
|
||||
NSString *duration, *quantity;
|
||||
unichar c;
|
||||
unsigned int i;
|
||||
|
||||
anAlarm = [[component alarms] objectAtIndex: 0];
|
||||
aTrigger = [anAlarm trigger];
|
||||
if ([[anAlarm action] caseInsensitiveCompare: @"DISPLAY"] == NSOrderedSame &&
|
||||
[[aTrigger valueType] caseInsensitiveCompare: @"DURATION"] == NSOrderedSame)
|
||||
{
|
||||
duration = [aTrigger value];
|
||||
i = [reminderValues indexOfObject: duration];
|
||||
|
||||
if (i == NSNotFound)
|
||||
{
|
||||
// Custom alarm
|
||||
ASSIGN (reminder, @"CUSTOM");
|
||||
ASSIGN (reminderRelation, [aTrigger relationType]);
|
||||
|
||||
i = 0;
|
||||
c = [duration characterAtIndex: i];
|
||||
if (c == '-')
|
||||
{
|
||||
ASSIGN (reminderReference, @"BEFORE");
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSIGN (reminderReference, @"AFTER");
|
||||
}
|
||||
|
||||
c = [duration characterAtIndex: i];
|
||||
if (c == 'P')
|
||||
{
|
||||
quantity = @"";
|
||||
// Parse duration -- ignore first character (P)
|
||||
for (i++; i < [duration length]; i++)
|
||||
{
|
||||
c = [duration characterAtIndex: i];
|
||||
if (c == 't' || c == 'T')
|
||||
// time -- ignore character
|
||||
continue;
|
||||
else if (isdigit (c))
|
||||
quantity = [quantity stringByAppendingFormat: @"%c", c];
|
||||
else
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case 'D': /* day */
|
||||
ASSIGN (reminderUnit, @"DAYS");
|
||||
break;
|
||||
case 'H': /* hour */
|
||||
ASSIGN (reminderUnit, @"HOURS");
|
||||
break;
|
||||
case 'M': /* min */
|
||||
ASSIGN (reminderUnit, @"MINUTES");
|
||||
break;
|
||||
default:
|
||||
NSLog(@"Cannot process duration unit: '%c'", c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ([quantity length])
|
||||
ASSIGN (reminderQuantity, quantity);
|
||||
}
|
||||
}
|
||||
else
|
||||
// Matches one of the predefined alarms
|
||||
ASSIGN (reminder, [reminderItems objectAtIndex: i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
|
@ -401,6 +544,7 @@ iRANGE(2);
|
|||
[self _loadCategories];
|
||||
[self _loadAttendees];
|
||||
[self _loadRRules];
|
||||
[self _loadAlarms];
|
||||
|
||||
[componentCalendar release];
|
||||
componentCalendar = [co container];
|
||||
|
@ -739,51 +883,28 @@ iRANGE(2);
|
|||
|
||||
- (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;
|
||||
// }
|
||||
- (void) setReminder: (NSString *) theReminder
|
||||
{
|
||||
ASSIGN(reminder, theReminder);
|
||||
}
|
||||
|
||||
- (NSString *) reminder
|
||||
{
|
||||
return @"";
|
||||
}
|
||||
{
|
||||
return reminder;
|
||||
}
|
||||
|
||||
- (void) setReminder: (NSString *) newReminder
|
||||
{
|
||||
}
|
||||
- (void) setReminderQuantity: (NSString *) theReminderQuantity
|
||||
{
|
||||
ASSIGN(reminderQuantity, theReminderQuantity);
|
||||
}
|
||||
|
||||
- (NSString *) reminderQuantity
|
||||
{
|
||||
return reminderQuantity;
|
||||
}
|
||||
|
||||
- (NSString *) itemReminderText
|
||||
{
|
||||
|
@ -1604,6 +1725,54 @@ RANGE(2);
|
|||
[component setPriority: priority];
|
||||
[component setLastModified: now];
|
||||
|
||||
if (!reminder || [reminder caseInsensitiveCompare: @"-"] == NSOrderedSame)
|
||||
// No alarm selected -- if there was an unsupported alarm defined in
|
||||
// the event, it will be deleted.
|
||||
[component removeAllAlarms];
|
||||
else
|
||||
{
|
||||
iCalTrigger *aTrigger;
|
||||
iCalAlarm *anAlarm;
|
||||
NSString *aValue;
|
||||
unsigned int index;
|
||||
|
||||
index = [reminderItems indexOfObject: reminder];
|
||||
aValue = [reminderValues objectAtIndex: index];
|
||||
|
||||
aTrigger = [iCalTrigger elementWithTag: @"TRIGGER"];
|
||||
[aTrigger setValueType: @"DURATION"];
|
||||
|
||||
anAlarm = [iCalAlarm new];
|
||||
[anAlarm setAction: @"DISPLAY"];
|
||||
[anAlarm setTrigger: aTrigger];
|
||||
|
||||
if ([aValue length]) {
|
||||
// Predefined alarm
|
||||
[aTrigger setValue: aValue];
|
||||
}
|
||||
else {
|
||||
// Custom alarm
|
||||
if ([reminderReference caseInsensitiveCompare: @"BEFORE"] == NSOrderedSame)
|
||||
aValue = [NSString stringWithString: @"-P"];
|
||||
else
|
||||
aValue = [NSString stringWithString: @"P"];
|
||||
|
||||
if ([reminderUnit caseInsensitiveCompare: @"MINUTES"] == NSOrderedSame ||
|
||||
[reminderUnit caseInsensitiveCompare: @"HOURS"] == NSOrderedSame)
|
||||
aValue = [aValue stringByAppendingString: @"T"];
|
||||
|
||||
aValue = [aValue stringByAppendingFormat: @"%i%@",
|
||||
[reminderQuantity intValue],
|
||||
[reminderUnit substringToIndex: 1]];
|
||||
[aTrigger setValue: aValue];
|
||||
[aTrigger setRelationType: reminderRelation];
|
||||
}
|
||||
[component removeAllAlarms];
|
||||
[component addToAlarms: anAlarm];
|
||||
|
||||
[anAlarm release];
|
||||
}
|
||||
|
||||
if (![self isChildOccurence])
|
||||
{
|
||||
// We remove any repeat rules
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
/* UIxReminderEditor.h - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2009 Inverse inc.
|
||||
*
|
||||
* Author: Francis Lachapelle <flachapelle@inverse.ca>
|
||||
*
|
||||
* This file is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This file is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef UIXREMINDEREDITOR_H
|
||||
#define UIXREMINDEREDITOR_H
|
||||
|
||||
#import <SOGoUI/UIxComponent.h>
|
||||
|
||||
@interface UIxReminderEditor : UIxComponent
|
||||
{
|
||||
NSString *item, *repeat;
|
||||
NSCalendarDate *aptStartDate;
|
||||
}
|
||||
|
||||
- (NSArray *) unitsList;
|
||||
- (NSArray *) referencesList;
|
||||
- (NSArray *) relationsList;
|
||||
|
||||
- (void) setItem: (NSString *) theItem;
|
||||
- (NSString *) item;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* UIXREMINDEREDITOR_H */
|
|
@ -0,0 +1,93 @@
|
|||
/* UIxReminderEditor.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2009 Inverse inc.
|
||||
*
|
||||
* Author: Francis Lachapelle <flachapelle@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/NSString.h>
|
||||
|
||||
#import <Common/UIxPageFrame.h>
|
||||
|
||||
#import "UIxReminderEditor.h"
|
||||
|
||||
@implementation UIxReminderEditor
|
||||
|
||||
- (NSArray *) unitsList
|
||||
{
|
||||
static NSArray *unitsList = nil;
|
||||
|
||||
if (!unitsList)
|
||||
{
|
||||
unitsList = [NSArray arrayWithObjects: @"MINUTES", @"HOURS", @"DAYS", nil];
|
||||
[unitsList retain];
|
||||
}
|
||||
|
||||
return unitsList;
|
||||
}
|
||||
|
||||
- (NSArray *) referencesList
|
||||
{
|
||||
static NSArray *referencesList = nil;
|
||||
|
||||
if (!referencesList)
|
||||
{
|
||||
referencesList = [NSArray arrayWithObjects: @"BEFORE", @"AFTER", nil];
|
||||
[referencesList retain];
|
||||
}
|
||||
|
||||
return referencesList;
|
||||
}
|
||||
|
||||
- (NSArray *) relationsList
|
||||
{
|
||||
static NSArray *relationsList = nil;
|
||||
|
||||
if (!relationsList)
|
||||
{
|
||||
relationsList = [NSArray arrayWithObjects: @"START", @"END", nil];
|
||||
[relationsList retain];
|
||||
}
|
||||
|
||||
return relationsList;
|
||||
}
|
||||
|
||||
- (void) setItem: (NSString *) theItem
|
||||
{
|
||||
item = theItem;
|
||||
}
|
||||
|
||||
- (NSString *) item
|
||||
{
|
||||
return item;
|
||||
}
|
||||
|
||||
- (NSString *) itemText
|
||||
{
|
||||
NSString *text;
|
||||
|
||||
if ([item isEqualToString: @"-"])
|
||||
text = item;
|
||||
else
|
||||
text = [self labelForKey: [NSString stringWithFormat: @"reminder_%@", item]];
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
@end
|
|
@ -1,6 +1,6 @@
|
|||
/* UIxTaskEditor.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2007 Inverse inc.
|
||||
* Copyright (C) 2007-2009 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -403,7 +403,10 @@
|
|||
if (hasDueDate)
|
||||
[todo setDue: taskDueDate];
|
||||
else
|
||||
[todo setDue: nil];
|
||||
{
|
||||
[todo setDue: nil];
|
||||
[todo removeAllAlarms];
|
||||
}
|
||||
|
||||
if ([status isEqualToString: @"COMPLETED"])
|
||||
[todo setCompleted: statusDate];
|
||||
|
|
|
@ -107,6 +107,10 @@
|
|||
protectedBy = "View";
|
||||
pageName = "UIxRecurrenceEditor";
|
||||
};
|
||||
editReminder = {
|
||||
protectedBy = "View";
|
||||
pageName = "UIxReminderEditor";
|
||||
};
|
||||
colorPicker = {
|
||||
protectedBy = "View";
|
||||
pageName = "UIxColorPicker";
|
||||
|
|
|
@ -76,7 +76,7 @@
|
|||
<label><var:string label:value="Repeat:" />
|
||||
<span class="content"><var:popup list="repeatList" item="item"
|
||||
label:noSelectionString="repeat_NEVER"
|
||||
var:disabled="isChildOccurence"
|
||||
var:disabled="isChildOccurence"
|
||||
const:disabledValue="-"
|
||||
const:name="repeatList"
|
||||
const:id="repeatList"
|
||||
|
@ -87,10 +87,12 @@
|
|||
<label><var:string label:value="Reminder:" />
|
||||
<span class="content"><var:popup list="reminderList" item="item"
|
||||
const:disabledValue="-"
|
||||
const:disabled="YES"
|
||||
label:noSelectionString="reminder_NONE"
|
||||
string="itemReminderText" selection="reminder"
|
||||
/></span></label>
|
||||
const:name="reminderList"
|
||||
const:id="reminderList"
|
||||
string="itemReminderText" var:selection="reminder"
|
||||
/> <a href="#" id="reminderHref" style="display: none;"
|
||||
><var:string label:value="Edit"/></a></span></label>
|
||||
<hr />
|
||||
<label id="commentArea"><var:string label:value="Description:"
|
||||
/><textarea rows="20" name="comment" var:value="comment" /></label>
|
||||
|
@ -148,6 +150,19 @@
|
|||
<input type="hidden" name="range2"
|
||||
id="range2"
|
||||
var:value="range2"/>
|
||||
|
||||
<input type="hidden" name="reminderQuantity"
|
||||
id="reminderQuantity"
|
||||
var:value="reminderQuantity"/>
|
||||
<input type="hidden" name="reminderUnit"
|
||||
id="reminderUnit"
|
||||
var:value="reminderUnit"/>
|
||||
<input type="hidden" name="reminderRelation"
|
||||
id="reminderRelation"
|
||||
var:value="reminderRelation"/>
|
||||
<input type="hidden" name="reminderReference"
|
||||
id="reminderReference"
|
||||
var:value="reminderReference"/>
|
||||
</div>
|
||||
</form>
|
||||
</var:component>
|
||||
|
|
|
@ -8,8 +8,10 @@
|
|||
xmlns:rsrc="OGo:url"
|
||||
xmlns:label="OGo:label"
|
||||
className="UIxComponentEditor"
|
||||
componentCalendar="componentCalendar"
|
||||
var:component="todo"
|
||||
var:saveURL="saveURL">
|
||||
|
||||
<span class="checkBoxList"><var:string label:value="Start:" />
|
||||
<span class="content"><input var:checked="hasStartDate"
|
||||
id="startDateCB" type="checkbox" class="checkBox"
|
||||
|
|
|
@ -4,5 +4,8 @@ SELECT#calendarList
|
|||
#attendeesLabel
|
||||
{ display: none; }
|
||||
|
||||
SPAN.datePicker INPUT.textField
|
||||
{ width: 7em; }
|
||||
|
||||
SPAN.timeDateControl A.button
|
||||
{ border: 0; }
|
||||
|
|
|
@ -132,7 +132,10 @@ function onComponentEditorLoad(event) {
|
|||
|
||||
$("repeatHref").observe("click", onPopupRecurrenceWindow);
|
||||
$("repeatList").observe("change", onPopupRecurrenceWindow);
|
||||
$("reminderHref").observe("click", onPopupReminderWindow);
|
||||
$("reminderList").observe("change", onPopupReminderWindow);
|
||||
onPopupRecurrenceWindow(null);
|
||||
onPopupReminderWindow(null);
|
||||
}
|
||||
|
||||
function onPopupRecurrenceWindow(event) {
|
||||
|
@ -153,4 +156,22 @@ function onPopupRecurrenceWindow(event) {
|
|||
return false;
|
||||
}
|
||||
|
||||
function onPopupReminderWindow(event) {
|
||||
if (event)
|
||||
preventDefault(event);
|
||||
|
||||
var reminderHref = $("reminderHref");
|
||||
|
||||
if ($("reminderList").value == 15) {
|
||||
reminderHref.show();
|
||||
if (event)
|
||||
window.open(ApplicationBaseURL + "editReminder", null,
|
||||
"width=250,height=150");
|
||||
}
|
||||
else
|
||||
reminderHref.hide();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
document.observe("dom:loaded", onComponentEditorLoad);
|
||||
|
|
|
@ -104,6 +104,3 @@ LABEL#urlArea INPUT
|
|||
|
||||
INPUT#statusPercent
|
||||
{ width: 2em; }
|
||||
|
||||
INPUT#statusTime_date
|
||||
{ width: 5em; }
|
||||
|
|
|
@ -164,6 +164,8 @@ function onTimeControlCheck(checkBox) {
|
|||
for (var i = 0; i < selects.length; i++)
|
||||
if (selects[i] != checkBox)
|
||||
selects[i].disabled = !checkBox.checked;
|
||||
if (checkBox.id == "dueDateCB")
|
||||
$("reminderList").disabled = !checkBox.checked;
|
||||
}
|
||||
|
||||
function saveEvent(sender) {
|
||||
|
@ -308,6 +310,9 @@ function onTaskEditorLoad() {
|
|||
'minute': $("dueTime_time_minute")}};
|
||||
initTimeWidgets(widgets);
|
||||
|
||||
// Enable or disable the reminder list
|
||||
onTimeControlCheck($("dueDateCB"));
|
||||
|
||||
initializeStatusLine();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue