merge of '8f8b8e1ba740753f2a06bacb246e4d9768d57753'

and 'f9e18ec89398d410d9a1603f1d30c2911cb74a44'

Monotone-Parent: 8f8b8e1ba740753f2a06bacb246e4d9768d57753
Monotone-Parent: f9e18ec89398d410d9a1603f1d30c2911cb74a44
Monotone-Revision: ab2613d820779df99f34c6d0ae2ec38908cae05f

Monotone-Author: wsourdeau@inverse.ca
Monotone-Date: 2010-04-19T21:25:30
Monotone-Branch: ca.inverse.sogo
This commit is contained in:
Wolfgang Sourdeau
2010-04-19 21:25:30 +00:00
18 changed files with 1123 additions and 648 deletions
+3 -19
View File
@@ -1,6 +1,6 @@
/* UIxAppointmentEditor.m - this file is part of SOGo
*
* Copyright (C) 2007-2009 Inverse inc.
* Copyright (C) 2007-2010 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
*
@@ -419,13 +419,11 @@
{
WOResponse *result;
NSDictionary *data;
NSCalendarDate *firstDate, *eventDate;
NSCalendarDate *eventDate;
NSTimeZone *timeZone;
SOGoUserDefaults *ud;
SOGoCalendarComponent *co;
iCalEvent *master;
BOOL resetAlarm;
signed int daylightOffset;
BOOL resetAlarm;
[self event];
@@ -457,20 +455,6 @@
[co saveComponent: event];
}
if ([co isNew] && [co isKindOfClass: [SOGoAppointmentOccurence class]])
{
// This is a new exception in a recurrent event -- compute the daylight
// saving time with respect to the first occurrence of the recurrent event.
master = (iCalEvent*)[[event parent] firstChildWithTag: @"vevent"];
firstDate = [master startDate];
if ([timeZone isDaylightSavingTimeForDate: eventDate] != [timeZone isDaylightSavingTimeForDate: firstDate])
{
daylightOffset = (signed int)[timeZone secondsFromGMTForDate: firstDate]
- (signed int)[timeZone secondsFromGMTForDate: eventDate];
eventDate = [eventDate dateByAddingYears:0 months:0 days:0 hours:0 minutes:0 seconds:daylightOffset];
}
}
data = [NSDictionary dictionaryWithObjectsAndKeys:
[componentCalendar displayName], @"calendar",
[event tag], @"component",
+20 -21
View File
@@ -273,27 +273,28 @@ static NSArray *tasksFields = nil;
static NSString *fields[] = { @"startDate", @"c_startdate",
@"endDate", @"c_enddate" };
for (count = 0; count < 2; count++)
{
aDateField = fields[count * 2];
aDate = [aRecord objectForKey: aDateField];
daylightOffset = (int) ([userTimeZone secondsFromGMTForDate: aDate]
- [userTimeZone secondsFromGMTForDate: startDate]);
if (daylightOffset)
{
aDate = [aDate dateByAddingYears: 0 months: 0 days: 0 hours: 0
minutes: 0 seconds: daylightOffset];
[aRecord setObject: aDate forKey: aDateField];
aDateValue = [NSNumber numberWithInt: [aDate timeIntervalSince1970]];
[aRecord setObject: aDateValue forKey: fields[count * 2 + 1]];
}
}
if (dayBasedView)
for (count = 0; count < 2; count++)
{
aDateField = fields[count * 2];
aDate = [aRecord objectForKey: aDateField];
daylightOffset = (int) ([userTimeZone secondsFromGMTForDate: aDate]
- [userTimeZone secondsFromGMTForDate: startDate]);
if (daylightOffset)
{
aDate = [aDate dateByAddingYears: 0 months: 0 days: 0 hours: 0
minutes: 0 seconds: daylightOffset];
[aRecord setObject: aDate forKey: aDateField];
aDateValue = [NSNumber numberWithInt: [aDate timeIntervalSince1970]];
[aRecord setObject: aDateValue forKey: fields[count * 2 + 1]];
}
}
aDateValue = [aRecord objectForKey: @"c_recurrence_id"];
aDate = [aRecord objectForKey: @"cycleStartDate"];
aStartDate = [aRecord objectForKey: @"startDate"];
if (aDateValue && aDate)
{
aStartDate = [aRecord objectForKey: @"startDate"];
if ([userTimeZone isDaylightSavingTimeForDate: aStartDate] !=
[userTimeZone isDaylightSavingTimeForDate: aDate])
{
@@ -387,11 +388,9 @@ static NSArray *tasksFields = nil;
forKey: @"c_owner"];
if (![[newInfo objectForKey: @"c_title"] length])
[self _fixComponentTitle: newInfo withType: component];
if (dayBasedView
|| [[newInfo objectForKey: @"c_isallday"] boolValue])
// Possible improvement: only call _fixDates if event is recurrent
// or the view range span a daylight saving time change
[self _fixDates: newInfo];
// Possible improvement: only call _fixDates if event is recurrent
// or the view range span a daylight saving time change
[self _fixDates: newInfo];
[infos addObject: [newInfo objectsForKeys: fields
notFoundMarker: marker]];
}
+103 -69
View File
@@ -31,6 +31,7 @@
#import <Foundation/NSURL.h>
#import <NGCards/iCalAlarm.h>
#import <NGCards/iCalByDayMask.h>
#import <NGCards/iCalPerson.h>
#import <NGCards/iCalRepeatableEntityObject.h>
#import <NGCards/iCalRecurrenceRule.h>
@@ -294,25 +295,6 @@ iRANGE(2);
}
}
- (NSString *) _dayMaskToInteger: (unsigned int) theMask
{
iCalWeekDay maskDays[] = {iCalWeekDaySunday, iCalWeekDayMonday,
iCalWeekDayTuesday, iCalWeekDayWednesday,
iCalWeekDayThursday, iCalWeekDayFriday,
iCalWeekDaySaturday};
unsigned int i;
NSMutableString *s;
s = [NSMutableString string];
for (i = 0; i < 7; i++)
if ((theMask & maskDays[i]))
[s appendFormat: @"%d,", i];
[s deleteSuffix: @","];
return s;
}
- (void) _loadRRules
{
SOGoUserDefaults *ud;
@@ -326,15 +308,12 @@ iRANGE(2);
rule = [[component recurrenceRules] lastObject];
/* DAILY */
if ([rule frequency] == iCalRecurrenceFrequenceDaily)
{
repeatType = @"0";
if ([rule byDayMask] == (iCalWeekDayMonday
| iCalWeekDayTuesday
| iCalWeekDayWednesday
| iCalWeekDayThursday
| iCalWeekDayFriday))
if ([[rule byDayMask] isWeekDays])
{
if ([rule isInfinite])
repeat = @"EVERY WEEKDAY";
@@ -350,12 +329,14 @@ iRANGE(2);
[self setRepeat2: [NSString stringWithFormat: @"%d", [rule repeatInterval]]];
}
}
/* WEEKLY */
else if ([rule frequency] == iCalRecurrenceFrequenceWeekly)
{
repeatType = @"1";
[self setRepeat1: [NSString stringWithFormat: @"%d", [rule repeatInterval]]];
if (![rule byDayMask])
if (![[rule byDay] length])
{
if ([rule repeatInterval] == 1)
repeat = @"WEEKLY";
@@ -364,45 +345,81 @@ iRANGE(2);
}
else
{
[self setRepeat2: [self _dayMaskToInteger: [rule byDayMask]]];
[self setRepeat2: [[rule byDayMask] asRuleStringWithIntegers]];
}
}
/* MONTHLY */
else if ([rule frequency] == iCalRecurrenceFrequenceMonthly)
{
repeatType = @"2";
if ([rule byDayMask])
if ([[rule byDay] length])
{
// TODO
int firstOccurrence;
iCalByDayMask *dayMask;
dayMask = [rule byDayMask];
firstOccurrence = [dayMask firstOccurrence] - 1;
if (firstOccurrence < 0)
firstOccurrence = 5;
[self setRepeat2: @"0"];
[self setRepeat3: [NSString stringWithFormat: @"%d", firstOccurrence]];
[self setRepeat4: [NSString stringWithFormat: @"%d", [dayMask firstDay]]];
}
else if ([[rule byMonthDay] count])
{
[self setRepeat2: @"1"];
[self setRepeat5: [[rule byMonthDay] componentsJoinedByString: @","]];
NSArray *days;
days = [rule byMonthDay];
if ([days count] > 0 && [[days objectAtIndex: 0] intValue] < 0)
{
// BYMONTHDAY=-1
[self setRepeat2: @"0"];
[self setRepeat3: @"5"]; // last ..
[self setRepeat4: @"7"]; // .. day of the month
}
else
{
[self setRepeat2: @"1"];
[self setRepeat5: [[rule byMonthDay] componentsJoinedByString: @","]];
}
}
else if ([rule repeatInterval] == 1)
repeat = @"MONTHLY";
[self setRepeat1: [NSString stringWithFormat: @"%d", [rule repeatInterval]]];
}
/* YEARLY */
else
{
repeatType = @"3";
if ([rule namedValue: @"bymonth"])
if ([[rule namedValue: @"bymonth"] length])
{
if (![rule byDayMask])
if ([[rule byDay] length])
{
int firstOccurrence;
iCalByDayMask *dayMask;
dayMask = [rule byDayMask];
firstOccurrence = [dayMask firstOccurrence] - 1;
if (firstOccurrence < 0)
firstOccurrence = 5;
[self setRepeat2: @"1"];
[self setRepeat5: [NSString stringWithFormat: @"%d", firstOccurrence]];
[self setRepeat6: [NSString stringWithFormat: @"%d", [dayMask firstDay]]];
[self setRepeat7: [NSString stringWithFormat: @"%d", [[rule namedValue: @"bymonth"] intValue]-1]];
}
else
{
[self setRepeat2: @"0"];
[self setRepeat3: [rule namedValue: @"bymonthday"]];
[self setRepeat4: [NSString stringWithFormat: @"%d", [[rule namedValue: @"bymonth"] intValue]-1]];
}
else
{
// TODO
[self setRepeat2: @"1"];
}
}
else if ([rule repeatInterval] == 1)
repeat = @"YEARLY";
@@ -410,7 +427,7 @@ iRANGE(2);
[self setRepeat1: [NSString stringWithFormat: @"%d", [rule repeatInterval]]];
}
// We decode the proper end date, recurrences count, etc.
/* We decode the proper end date, recurrences count, etc. */
if ([rule repeatCount])
{
repeat = @"CUSTOM";
@@ -1639,9 +1656,9 @@ RANGE(2);
switch (type)
{
// DAILY:
// DAILY (0)
//
// repeat1 holds the value of the radio button:
// repeat1 holds the value of the frequency radio button:
// 0 -> Every X days
// 1 -> Every weekday
//
@@ -1653,11 +1670,7 @@ RANGE(2);
if ([[self repeat1] intValue] > 0)
{
[theRule setByDayMask: (iCalWeekDayMonday
|iCalWeekDayTuesday
|iCalWeekDayWednesday
|iCalWeekDayThursday
|iCalWeekDayFriday)];
[theRule setByDayMask: [iCalByDayMask byDayMaskWithWeekDays]];
}
else
{
@@ -1670,7 +1683,7 @@ RANGE(2);
}
break;
// WEEKLY
// WEEKLY (1)
//
// repeat1 holds the value of "Every X week(s)"
//
@@ -1683,7 +1696,8 @@ RANGE(2);
if ([[self repeat1] intValue] > 0)
{
NSArray *v;
int c, mask;
int c, day;
iCalWeekOccurrences days;
[theRule setFrequency: iCalRecurrenceFrequenceWeekly];
[theRule setInterval: [self repeat1]];
@@ -1692,18 +1706,21 @@ RANGE(2);
{
v = [[self repeat2] componentsSeparatedByString: @","];
c = [v count];
mask = 0;
memset(days, 0, 7 * sizeof(iCalWeekOccurrence));
while (c--)
mask |= 1 << ([[v objectAtIndex: c] intValue]);
[theRule setByDayMask: mask];
{
day = [[v objectAtIndex: c] intValue];
if (day >= 0 && day <= 7)
days[day] = iCalWeekOccurrenceAll;
}
[theRule setByDayMask: [iCalByDayMask byDayMaskWithDays: days]];
}
}
}
break;
// MONTHLY
// MONTHLY (2)
//
// repeat1 holds the value of "Every X month(s)"
//
@@ -1731,20 +1748,29 @@ RANGE(2);
[theRule setInterval: [self repeat1]];
// We recur on specific days...
if ([[self repeat2] intValue] == 1
&& [[self repeat5] intValue] > 0)
{
[theRule setNamedValue: @"bymonthday" to: [self repeat5]];
}
else
{
// TODO
}
if ([[self repeat2] intValue] == 0)
{
NSString *day;
int occurence;
day = [theRule iCalRepresentationForWeekDay: [[self repeat4] intValue]];
occurence = [[self repeat3] intValue] + 1;
if (occurence > 5) // the first/second/third/fourth/fifth ..
occurence = -1; // the last ..
[theRule setNamedValue: @"byday"
to: [NSString stringWithFormat: @"%d%@",
occurence, day]];
}
else
{
if ([[self repeat5] intValue] > 0)
[theRule setNamedValue: @"bymonthday" to: [self repeat5]];
}
}
}
break;
// YEARLY
// YEARLY (3)
//
// repeat1 holds the value of "Every X year(s)"
//
@@ -1756,7 +1782,7 @@ RANGE(2);
// repeat4 holds the value of the MONTH parameter (0 -> January, 1 -> February ... )
// ex: 3 February
//
// repeat5 holds the value of the OCCURENCE parameter (0 -> First, 1 -> Second ..)
// repeat5 holds the value of the OCCURENCE parameter (0 -> First, 1 -> Second .., 5 -> Last)
// repeat6 holds the value of the DAY parameter (0 -> Sunday, 1 -> Monday, etc..)
// repeat7 holds the value of the MONTH parameter (0 -> January, 1 -> February ... )
//
@@ -1771,7 +1797,19 @@ RANGE(2);
// We recur Every .. of ..
if ([[self repeat2] intValue] == 1)
{
// TODO
NSString *day;
int occurence;
day = [theRule iCalRepresentationForWeekDay: [[self repeat6] intValue]];
occurence = [[self repeat5] intValue] + 1;
if (occurence > 5) // the first/second/third/fourth/fifth ..
occurence = -1; // the last ..
[theRule setNamedValue: @"byday"
to: [NSString stringWithFormat: @"%d%@",
occurence, day]];
[theRule setNamedValue: @"bymonth"
to: [NSString stringWithFormat: @"%d",
[[self repeat7] intValue] + 1]];
}
else
{
@@ -1883,11 +1921,7 @@ RANGE(2);
}
else if ([repeat caseInsensitiveCompare: @"EVERY WEEKDAY"] == NSOrderedSame)
{
[rule setByDayMask: (iCalWeekDayMonday
|iCalWeekDayTuesday
|iCalWeekDayWednesday
|iCalWeekDayThursday
|iCalWeekDayFriday)];
[rule setByDayMask: [iCalByDayMask byDayMaskWithWeekDays]];
[rule setFrequency: iCalRecurrenceFrequenceDaily];
}
else if ([repeat caseInsensitiveCompare: @"MONTHLY"] == NSOrderedSame
+48 -55
View File
@@ -241,32 +241,26 @@ function handleMonthlyRecurrence() {
var radioValue = $('recurrence_form').getRadioValue('monthlyRadioButtonName');
// FIXME - right now we do not support rules
// such as The Second Tuesday...
if (radioValue == 0)
window.alert(recurrenceUnsupported);
else {
// We check if the monthlyMonthsField really contains an integer
var showError = true;
// We check if the monthlyMonthsField really contains an integer
var showError = true;
var fieldValue = "" + $('monthlyMonthsField').value;
if (fieldValue.length > 0) {
var v = parseInt(fieldValue);
if (!isNaN(v) && v > 0) {
validate = true;
showError = false;
parent$("repeat1").value = fieldValue;
parent$("repeat2").value = radioValue;
parent$("repeat3").value = $('monthlyRepeat').value;
parent$("repeat4").value = $('monthlyDay').value;
parent$("repeat5").value = getSelectedDays("month");
}
var fieldValue = "" + $('monthlyMonthsField').value;
if (fieldValue.length > 0) {
var v = parseInt(fieldValue);
if (!isNaN(v) && v > 0) {
validate = true;
showError = false;
parent$("repeat1").value = fieldValue;
parent$("repeat2").value = radioValue;
parent$("repeat3").value = $('monthlyRepeat').value;
parent$("repeat4").value = $('monthlyDay').value;
parent$("repeat5").value = getSelectedDays("month");
}
if (showError)
window.alert(monthFieldInvalid);
}
if (showError)
window.alert(monthFieldInvalid);
return validate;
}
@@ -279,15 +273,20 @@ function validateYearlyRecurrence() {
// We check if the yearlyYearsField really contains an integer
var v = parseInt(fieldValue);
if (!isNaN(v) && v > 0) {
errorToShow = 1;
fieldValue = "" + $('yearlyDayField').value;
if (fieldValue.length > 0) {
// We check if the yearlyYearsField really contains an integer
var v = parseInt(fieldValue);
if (!isNaN(v) && v > 0) {
errorToShow = -1;
var radioValue = $('recurrence_form').getRadioValue('yearlyRadioButtonName');
if (radioValue == 0) {
errorToShow = 1;
fieldValue = "" + $('yearlyDayField').value;
if (fieldValue.length > 0) {
// We check if the yearlyDayField really contains an integer
var v = parseInt(fieldValue);
if (!isNaN(v) && v > 0) {
errorToShow = -1;
}
}
}
else
errorToShow = -1;
}
}
@@ -300,34 +299,28 @@ function validateYearlyRecurrence() {
function handleYearlyRecurrence() {
var validate = false;
var radioValue = $('recurrence_form').getRadioValue('yearlyRadioButtonName');
// FIXME - right now we do not support rules
// such as Every Second Tuesday of February
if (radioValue == 1)
window.alert(recurrenceUnsupported);
else {
if (validateYearlyRecurrence()) {
var fieldValue = "" + $('yearlyYearsField').value;
if (fieldValue.length > 0) {
// We check if the yearlyYearsField really contains an integer
var v = parseInt(fieldValue);
if (!isNaN(v) && v > 0) {
validate = true;
showError = false;
parent$("repeat1").value = fieldValue;
parent$("repeat2").value = radioValue;
parent$("repeat3").value = $('yearlyDayField').value;
parent$("repeat4").value = $('yearlyMonth1').value;
parent$("repeat5").value = $('yearlyRepeat').value;
parent$("repeat6").value = $('yearlyDay').value;
parent$("repeat7").value = $('yearlyMonth2').value;
}
if (validateYearlyRecurrence()) {
var radioValue = $('recurrence_form').getRadioValue('yearlyRadioButtonName');
var fieldValue = "" + $('yearlyYearsField').value;
if (fieldValue.length > 0) {
// We check if the yearlyYearsField (interval) really contains an integer
var v = parseInt(fieldValue);
if (!isNaN(v) && v > 0) {
validate = true;
showError = false;
parent$("repeat1").value = fieldValue;
parent$("repeat2").value = radioValue;
parent$("repeat3").value = $('yearlyDayField').value;
parent$("repeat4").value = $('yearlyMonth1').value;
parent$("repeat5").value = $('yearlyRepeat').value;
parent$("repeat6").value = $('yearlyDay').value;
parent$("repeat7").value = $('yearlyMonth2').value;
}
}
else
validate = false;
}
else
validate = false;
return validate;
}