mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-04-01 03:22:43 +00:00
merge of '779e2b1c502021e5eb405fa6e452d4a40ce77b6e'
and 'c4b00c603f23bbc97a3d07724c6b2a4e9361c098' Monotone-Parent: 779e2b1c502021e5eb405fa6e452d4a40ce77b6e Monotone-Parent: c4b00c603f23bbc97a3d07724c6b2a4e9361c098 Monotone-Revision: b062a471e751aff2d35891675a50d0fff8918047 Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2011-04-19T22:06:05 Monotone-Branch: ca.inverse.sogo
This commit is contained in:
20
ChangeLog
20
ChangeLog
@@ -36,8 +36,28 @@
|
||||
* OpenChange/MAPIStoreFolder.m (-createMessage): no longer a
|
||||
mandatory method. Returns nil when not overriden.
|
||||
|
||||
2011-04-19 Francis Lachapelle <flachapelle@inverse.ca>
|
||||
|
||||
* SoObjects/Appointments/SOGoAppointmentFolder.m
|
||||
(-_flattenCycleRecord:forRange:intoArray:): fixed the
|
||||
verification of the event's timezone.
|
||||
|
||||
2011-04-15 Francis Lachapelle <flachapelle@inverse.ca>
|
||||
|
||||
* SoObjects/Appointments/iCalEvent+SOGo.m (-firstOccurenceRange):
|
||||
we now compute the end date by looking at the occurrence
|
||||
interval. This way, we support events with an end date or a duration.
|
||||
|
||||
* SoObjects/Appointments/SOGoAppointmentFolder.m
|
||||
(-_flattenCycleRecord:forRange:intoArray:): also compute the end
|
||||
date by looking at the occurrence interval.
|
||||
(-importCalendar:): added a duration to events with no end date nor duration.
|
||||
|
||||
* SoObjects/Appointments/SOGoAppointmentObject.m
|
||||
(-_adjustEventsInRequest:): new method to verify the vCalendar for
|
||||
any inconsistency or missing attributes. Currently, it only adds a
|
||||
duration if no end date nor duration is found.
|
||||
|
||||
* UI/WebServerResources/ckeditor/config.js: Changed the default
|
||||
enter mode to use BR instead of P. This matches the behavior of Thunderbird.
|
||||
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
- (BOOL) hasEndDate;
|
||||
|
||||
- (NSString *) duration;
|
||||
- (void) setDuration: (NSString *) _value;
|
||||
- (BOOL) hasDuration;
|
||||
- (NSTimeInterval) durationAsTimeInterval;
|
||||
|
||||
|
||||
@@ -73,6 +73,7 @@
|
||||
#import <SOGo/WOResponse+SOGo.h>
|
||||
|
||||
#import "iCalRepeatableEntityObject+SOGo.h"
|
||||
#import "iCalEvent+SOGo.h"
|
||||
#import "iCalPerson+SOGo.h"
|
||||
#import "SOGoAppointmentObject.h"
|
||||
#import "SOGoAppointmentFolders.h"
|
||||
@@ -849,9 +850,9 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
||||
NSArray *rules, *exRules, *exDates, *ranges;
|
||||
NSArray *elements, *components;
|
||||
NSString *content;
|
||||
iCalRepeatableEntityObject *component;
|
||||
id firstStartDate, firstEndDate;
|
||||
NSCalendarDate *checkStartDate, *checkEndDate;
|
||||
iCalDateTime *dtstart;
|
||||
NSCalendarDate *checkStartDate, *checkEndDate, *firstStartDate, *firstEndDate;
|
||||
iCalEvent *component;
|
||||
iCalTimeZone *eventTimeZone;
|
||||
unsigned count, max, offset;
|
||||
|
||||
@@ -889,53 +890,55 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
||||
{
|
||||
// Retrieve the range of the first/master event
|
||||
component = [components objectAtIndex: 0];
|
||||
firstStartDate = [component uniqueChildWithTag: @"dtstart"];
|
||||
firstEndDate = [component uniqueChildWithTag: @"dtend"];
|
||||
eventTimeZone = [(iCalDateTime*)firstStartDate timeZone];
|
||||
firstRange = [NGCalendarDateRange calendarDateRangeWithStartDate: [[[firstStartDate values] lastObject] asCalendarDate]
|
||||
endDate: [[[firstEndDate values] lastObject] asCalendarDate]];
|
||||
dtstart = (iCalDateTime *)[component uniqueChildWithTag: @"dtstart"];
|
||||
firstStartDate = [[[dtstart values] lastObject] asCalendarDate];
|
||||
firstEndDate = [firstStartDate addTimeInterval: [component occurenceInterval]];
|
||||
|
||||
firstRange = [NGCalendarDateRange calendarDateRangeWithStartDate: firstStartDate
|
||||
endDate: firstEndDate];
|
||||
|
||||
if (eventTimeZone)
|
||||
{
|
||||
// Adjust the range to check with respect to the event timezone (extracted from the start date)
|
||||
checkStartDate = [eventTimeZone computedDateForDate: [theRange startDate]];
|
||||
checkEndDate = [eventTimeZone computedDateForDate: [theRange endDate]];
|
||||
recurrenceRange = [NGCalendarDateRange calendarDateRangeWithStartDate: checkStartDate
|
||||
endDate: checkEndDate];
|
||||
|
||||
// Adjust the exception dates
|
||||
exDates = [eventTimeZone computedDatesForStrings: exDates];
|
||||
|
||||
// Adjust the recurrence rules "until" dates
|
||||
rules = [component recurrenceRulesWithTimeZone: eventTimeZone];
|
||||
exRules = [component exceptionRulesWithTimeZone: eventTimeZone];
|
||||
}
|
||||
else
|
||||
{
|
||||
recurrenceRange = theRange;
|
||||
if ([[theRecord objectForKey: @"c_isallday"] boolValue])
|
||||
{
|
||||
// The event lasts all-day and has no timezone (floating); we convert the range of the first event
|
||||
// to the user's timezone
|
||||
offset = [timeZone secondsFromGMTForDate: [firstRange startDate]];
|
||||
firstStartDate = (NSCalendarDate*)[[firstRange startDate] dateByAddingYears:0 months:0 days:0 hours:0 minutes:0
|
||||
seconds:-offset];
|
||||
firstEndDate = (NSCalendarDate*)[[firstRange endDate] dateByAddingYears:0 months:0 days:0 hours:0 minutes:0
|
||||
seconds:-offset];
|
||||
[firstStartDate setTimeZone: timeZone];
|
||||
[firstEndDate setTimeZone: timeZone];
|
||||
firstRange = [NGCalendarDateRange calendarDateRangeWithStartDate: firstStartDate
|
||||
endDate: firstEndDate];
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate the occurrences for the given range
|
||||
eventTimeZone = [dtstart timeZone];
|
||||
if (eventTimeZone)
|
||||
{
|
||||
// Adjust the range to check with respect to the event timezone (extracted from the start date)
|
||||
checkStartDate = [eventTimeZone computedDateForDate: [theRange startDate]];
|
||||
checkEndDate = [eventTimeZone computedDateForDate: [theRange endDate]];
|
||||
recurrenceRange = [NGCalendarDateRange calendarDateRangeWithStartDate: checkStartDate
|
||||
endDate: checkEndDate];
|
||||
|
||||
// Adjust the exception dates
|
||||
exDates = [eventTimeZone computedDatesForStrings: exDates];
|
||||
|
||||
// Adjust the recurrence rules "until" dates
|
||||
rules = [component recurrenceRulesWithTimeZone: eventTimeZone];
|
||||
exRules = [component exceptionRulesWithTimeZone: eventTimeZone];
|
||||
}
|
||||
else
|
||||
{
|
||||
recurrenceRange = theRange;
|
||||
if ([[theRecord objectForKey: @"c_isallday"] boolValue])
|
||||
{
|
||||
// The event lasts all-day and has no timezone (floating); we convert the range of the first event
|
||||
// to the user's timezone
|
||||
offset = [timeZone secondsFromGMTForDate: [firstRange startDate]];
|
||||
firstStartDate = [[firstRange startDate] dateByAddingYears:0 months:0 days:0 hours:0 minutes:0
|
||||
seconds:-offset];
|
||||
firstEndDate = [[firstRange endDate] dateByAddingYears:0 months:0 days:0 hours:0 minutes:0
|
||||
seconds:-offset];
|
||||
[firstStartDate setTimeZone: timeZone];
|
||||
[firstEndDate setTimeZone: timeZone];
|
||||
firstRange = [NGCalendarDateRange calendarDateRangeWithStartDate: firstStartDate
|
||||
endDate: firstEndDate];
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate the occurrences for the given range
|
||||
records = [NSMutableArray array];
|
||||
ranges = [iCalRecurrenceCalculator recurrenceRangesWithinCalendarDateRange: recurrenceRange
|
||||
firstInstanceCalendarDateRange: firstRange
|
||||
ranges = [iCalRecurrenceCalculator recurrenceRangesWithinCalendarDateRange: recurrenceRange
|
||||
firstInstanceCalendarDateRange: firstRange
|
||||
recurrenceRules: rules
|
||||
exceptionRules: exRules
|
||||
exceptionDates: exDates];
|
||||
exceptionRules: exRules
|
||||
exceptionDates: exDates];
|
||||
max = [ranges count];
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
@@ -947,15 +950,15 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
||||
if (fixedRow)
|
||||
[records addObject: fixedRow];
|
||||
}
|
||||
|
||||
|
||||
[self _appendCycleExceptionsFromRow: row
|
||||
firstInstanceCalendarDateRange: firstRange
|
||||
forRange: theRange
|
||||
toArray: records];
|
||||
|
||||
|
||||
[theRecords addObjectsFromArray: records];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
[self errorWithFormat:@"cyclic record doesn't have content -> %@", theRecord];
|
||||
@@ -2607,6 +2610,11 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
||||
return ([object saveContentString: content] == nil);
|
||||
}
|
||||
|
||||
/**
|
||||
* Import all components of a vCalendar.
|
||||
* @param calendar the calendar to import
|
||||
* @return the number of components imported
|
||||
*/
|
||||
- (int) importCalendar: (iCalCalendar *) calendar
|
||||
{
|
||||
NSArray *vtimezones;
|
||||
@@ -2616,6 +2624,7 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
||||
iCalEntityObject *element;
|
||||
iCalDateTime *startDate;
|
||||
iCalTimeZone *timezone;
|
||||
iCalEvent *event;
|
||||
|
||||
int imported, count, i;
|
||||
|
||||
@@ -2651,6 +2660,20 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
||||
{
|
||||
timezone = [startDate timeZone];
|
||||
tz = [timezones valueForKey: [timezone tzId]];
|
||||
if ([element isKindOfClass: [iCalEvent class]])
|
||||
{
|
||||
event = (iCalEvent *)element;
|
||||
if (![event hasEndDate] && ![event hasDuration])
|
||||
{
|
||||
// No end date, no duration
|
||||
if ([event isAllDay])
|
||||
[event setDuration: @"P1D"];
|
||||
else
|
||||
[event setDuration: @"PT1H"];
|
||||
|
||||
[self errorWithFormat: @"Importing event with no end date; setting duration to %@", [event duration]];
|
||||
}
|
||||
}
|
||||
}
|
||||
if ([self importComponent: element
|
||||
timezone: (tz == nil? @"" : tz)])
|
||||
|
||||
@@ -1336,6 +1336,44 @@
|
||||
[rq setContent: [[calendar versitString] dataUsingEncoding: [rq contentEncoding]]];
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify vCalendar for any inconsistency or missing attributes.
|
||||
* Currently only check if the events have an end date or a duration.
|
||||
* @param rq the HTTP PUT request
|
||||
*/
|
||||
- (void) _adjustEventsInRequest: (WORequest *) rq
|
||||
{
|
||||
iCalCalendar *calendar;
|
||||
NSArray *allEvents;
|
||||
iCalEvent *event;
|
||||
NSUInteger i;
|
||||
BOOL modified;
|
||||
|
||||
calendar = [iCalCalendar parseSingleFromSource: [rq contentAsString]];
|
||||
allEvents = [calendar events];
|
||||
modified = NO;
|
||||
|
||||
for (i = 0; i < [allEvents count]; i++)
|
||||
{
|
||||
event = [allEvents objectAtIndex: i];
|
||||
|
||||
if (![event hasEndDate] && ![event hasDuration])
|
||||
{
|
||||
// No end date, no duration
|
||||
if ([event isAllDay])
|
||||
[event setDuration: @"P1D"];
|
||||
else
|
||||
[event setDuration: @"PT1H"];
|
||||
|
||||
modified = YES;
|
||||
[self errorWithFormat: @"Invalid event: no end date; setting duration to %@", [event duration]];
|
||||
}
|
||||
}
|
||||
|
||||
if (modified)
|
||||
[rq setContent: [[calendar versitString] dataUsingEncoding: [rq contentEncoding]]];
|
||||
}
|
||||
|
||||
- (void) _decomposeGroupsInRequest: (WORequest *) rq
|
||||
{
|
||||
iCalCalendar *calendar;
|
||||
@@ -1471,6 +1509,8 @@
|
||||
{
|
||||
[self _adjustTransparencyInRequest: rq];
|
||||
}
|
||||
|
||||
[self _adjustEventsInRequest: rq];
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
@interface iCalEvent (SOGoExtensions)
|
||||
|
||||
- (BOOL) isStillRelevant;
|
||||
- (unsigned int) occurenceInterval;
|
||||
- (NSMutableDictionary *) quickRecord;
|
||||
- (void) updateRecurrenceRulesUntilDate: (NSCalendarDate *) previousEndDate;
|
||||
|
||||
|
||||
@@ -272,14 +272,22 @@
|
||||
*/
|
||||
- (NGCalendarDateRange *) firstOccurenceRange
|
||||
{
|
||||
iCalDateTime *firstStartDate, *firstEndDate;
|
||||
iCalDateTime *firstStartDate;
|
||||
NSCalendarDate *start, *end;
|
||||
NGCalendarDateRange *firstRange;
|
||||
|
||||
firstStartDate = (iCalDateTime *)[self uniqueChildWithTag: @"dtstart"];
|
||||
firstEndDate = (iCalDateTime *)[self uniqueChildWithTag: @"dtend"];
|
||||
firstRange = [NGCalendarDateRange calendarDateRangeWithStartDate: [[[firstStartDate values] lastObject] asCalendarDate]
|
||||
endDate: [[[firstEndDate values] lastObject] asCalendarDate]];
|
||||
firstRange = nil;
|
||||
|
||||
firstStartDate = (iCalDateTime *)[self uniqueChildWithTag: @"dtstart"];
|
||||
if ([[firstStartDate values] count] > 0)
|
||||
{
|
||||
start = [[[firstStartDate values] lastObject] asCalendarDate];
|
||||
end = [start addTimeInterval: [self occurenceInterval]];
|
||||
|
||||
firstRange = [NGCalendarDateRange calendarDateRangeWithStartDate: start
|
||||
endDate: end];
|
||||
}
|
||||
|
||||
return firstRange;
|
||||
}
|
||||
|
||||
|
||||
@@ -131,8 +131,8 @@
|
||||
firstRange = [self firstOccurenceRange];
|
||||
|
||||
// Set the range to check with respect to the event timezone (extracted from the start date)
|
||||
firstStartDate = (iCalDateTime*) [self uniqueChildWithTag: @"dtstart"];
|
||||
eventTimeZone = [(iCalDateTime*) firstStartDate timeZone];
|
||||
firstStartDate = (iCalDateTime *)[self uniqueChildWithTag: @"dtstart"];
|
||||
eventTimeZone = [(iCalDateTime *)firstStartDate timeZone];
|
||||
if (eventTimeZone)
|
||||
startDate = [eventTimeZone computedDateForDate: theOccurenceDate];
|
||||
else
|
||||
@@ -144,12 +144,12 @@
|
||||
// to the occurence's timezone.
|
||||
timeZone = [theOccurenceDate timeZone];
|
||||
offset = [timeZone secondsFromGMTForDate: [firstRange startDate]];
|
||||
firstStartDate = (NSCalendarDate*) [[firstRange startDate] dateByAddingYears:0 months:0 days:0 hours:0 minutes:0
|
||||
firstStartDate = (NSCalendarDate *)[[firstRange startDate] dateByAddingYears:0 months:0 days:0 hours:0 minutes:0
|
||||
seconds:-offset];
|
||||
firstEndDate = (NSCalendarDate*) [[firstRange endDate] dateByAddingYears:0 months:0 days:0 hours:0 minutes:0
|
||||
firstEndDate = (NSCalendarDate *)[[firstRange endDate] dateByAddingYears:0 months:0 days:0 hours:0 minutes:0
|
||||
seconds:-offset];
|
||||
[(NSCalendarDate*) firstStartDate setTimeZone: timeZone];
|
||||
[(NSCalendarDate*) firstEndDate setTimeZone: timeZone];
|
||||
[(NSCalendarDate *)firstStartDate setTimeZone: timeZone];
|
||||
[(NSCalendarDate *)firstEndDate setTimeZone: timeZone];
|
||||
firstRange = [NGCalendarDateRange calendarDateRangeWithStartDate: firstStartDate
|
||||
endDate: firstEndDate];
|
||||
}
|
||||
|
||||
@@ -178,7 +178,6 @@ static NSArray *commonSearchFields;
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
NSLog(@"LDAPSource: -dealloc");
|
||||
[bindDN release];
|
||||
[hostname release];
|
||||
[encryption release];
|
||||
|
||||
@@ -1295,7 +1295,7 @@ function initContacts(event) {
|
||||
if (table) {
|
||||
// Initialize event delegation on contacts table
|
||||
table.multiselect = true;
|
||||
var tbody = table.tBodies[0];
|
||||
var tbody = $(table.tBodies[0]);
|
||||
tbody.on("mousedown", onContactSelectionChange);
|
||||
tbody.on("dblclick", onContactRowDblClick);
|
||||
tbody.on("selectstart", listRowMouseDownHandler);
|
||||
|
||||
@@ -141,7 +141,7 @@ SOGoTabsController.prototype = {
|
||||
this.activeTab = $(clickedTab);
|
||||
this.activeTab.addClassName("active"); // current LI
|
||||
content.addClassName("active");
|
||||
event.stop();
|
||||
|
||||
// Prototype alternative
|
||||
|
||||
//oldContent.removeClassName("active");
|
||||
|
||||
@@ -195,8 +195,8 @@ rm -fr ${RPM_BUILD_ROOT}
|
||||
%{prefix}/Library/OCSTypeModels/contact-oracle.ocs
|
||||
%{prefix}/Library/WOxElemBuilders-%{sope_version}/SOGoElements.wox
|
||||
|
||||
%config %{_sysconfdir}/httpd/conf.d/SOGo.conf
|
||||
%config %{_sysconfdir}/sysconfig/sogo
|
||||
%config(noreplace) %{_sysconfdir}/httpd/conf.d/SOGo.conf
|
||||
%config(noreplace) %{_sysconfdir}/sysconfig/sogo
|
||||
%doc ChangeLog NEWS Scripts/sql-update-20070724.sh Scripts/sql-update-20070822.sh Scripts/sql-update-20080303.sh Scripts/sql-update-101_to_102.sh Scripts/sql-update-1.2.2_to_1.3.0.sh Scripts/sql-update-1.2.2_to_1.3.0-mysql.sh Scripts/sql-update-1.3.3_to_1.3.4.sh Scripts/sql-update-1.3.3_to_1.3.4-mysql.sh
|
||||
|
||||
%files -n sogo-tool
|
||||
|
||||
Reference in New Issue
Block a user