See ChangeLogs

Monotone-Parent: e2ba584b1367987b411373efc53338c1daf189da
Monotone-Revision: ea7589320f5747a3bd1bbec33e1bd8776e4041db

Monotone-Author: flachapelle@inverse.ca
Monotone-Date: 2009-04-21T14:34:22
Monotone-Branch: ca.inverse.sogo
maint-2.0.2
Francis Lachapelle 2009-04-21 14:34:22 +00:00
parent 3b9d0b83cf
commit fa7408ebc1
26 changed files with 602 additions and 70 deletions

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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;

View File

@ -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__ */

View File

@ -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 */

View File

@ -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;
}

View File

@ -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%";

View File

@ -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%";

View File

@ -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%";

View File

@ -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 += \

View File

@ -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%";

View File

@ -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%";

View File

@ -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%";

View File

@ -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;

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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];

View File

@ -107,6 +107,10 @@
protectedBy = "View";
pageName = "UIxRecurrenceEditor";
};
editReminder = {
protectedBy = "View";
pageName = "UIxReminderEditor";
};
colorPicker = {
protectedBy = "View";
pageName = "UIxColorPicker";

View File

@ -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>

View File

@ -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"

View File

@ -4,5 +4,8 @@ SELECT#calendarList
#attendeesLabel
{ display: none; }
SPAN.datePicker INPUT.textField
{ width: 7em; }
SPAN.timeDateControl A.button
{ border: 0; }

View File

@ -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);

View File

@ -104,6 +104,3 @@ LABEL#urlArea INPUT
INPUT#statusPercent
{ width: 2em; }
INPUT#statusTime_date
{ width: 5em; }

View File

@ -55,7 +55,7 @@ function validateTaskEditor() {
if (!enddate)
return false;
}
if (startdate && enddate) {
tmpdate = uixEarlierDate(startdate, enddate);
if (tmpdate == enddate) {
@ -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) {
@ -307,7 +309,10 @@ function onTaskEditorLoad() {
'hour': $("dueTime_time_hour"),
'minute': $("dueTime_time_minute")}};
initTimeWidgets(widgets);
// Enable or disable the reminder list
onTimeControlCheck($("dueDateCB"));
initializeStatusLine();
}