mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-08-19 13:43:22 +00:00
merge of '3f8608c82d9c379cc9e0fea6ffe853cc1949a24b'
and '7634b9d503d61b6240548e75e7f872081debc6b4' Monotone-Parent: 3f8608c82d9c379cc9e0fea6ffe853cc1949a24b Monotone-Parent: 7634b9d503d61b6240548e75e7f872081debc6b4 Monotone-Revision: a4c7e35d642045e63467a131fae8049524f450e4 Monotone-Author: flachapelle@inverse.ca Monotone-Date: 2012-06-30T18:20:30 Monotone-Branch: ca.inverse.sogo
This commit is contained in:
@@ -67,4 +67,4 @@ vtodo_class2 = "(Skrytý úkol)";
|
||||
= "%{Attendee} %{SentByText}dosud o Vaší pozvánce k události nerozhodl/a.";
|
||||
|
||||
/* Resources */
|
||||
"Maximum number of simultaneous bookings (%{NumberOfSimultaneousBookings}) reached for resource \"%{Cn} %{SystemEmail}\"." = "Maximální počet současných rezervací (%{NumberOfSimultaneousBookings}) byl dosažen pro zdroj \"%{Cn} %{SystemEmail}\".";
|
||||
"Maximum number of simultaneous bookings (%{NumberOfSimultaneousBookings}) reached for resource \"%{Cn} %{SystemEmail}\". The conflicting event is \"%{EventTitle}\", and starts on %{StartDate}." = "Byl dosažen maximální počet současných rezervací\n(%{NumberOfSimultaneousBookings}) pro zdroj \"%{Cn} %{SystemEmail}\". Konfliktní událost je \"%{EventTitle}\" a začíná %{StartDate}.";
|
||||
@@ -2764,7 +2764,7 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
||||
iCalEvent *event;
|
||||
|
||||
int imported, count, i;
|
||||
|
||||
|
||||
imported = 0;
|
||||
|
||||
if (calendar)
|
||||
@@ -2799,6 +2799,41 @@ firstInstanceCalendarDateRange: (NGCalendarDateRange *) fir
|
||||
tzId = [startDate value: 0 ofAttribute: @"tzid"];
|
||||
if ([tzId length])
|
||||
timezone = [timezones valueForKey: tzId];
|
||||
else
|
||||
{
|
||||
// If the start date is a "floating time", let's use the user's timezone
|
||||
// during the import for both the start and end dates.
|
||||
NSString *s;
|
||||
|
||||
s = [[startDate valuesAtIndex: 0 forKey: @""] objectAtIndex: 0];
|
||||
|
||||
if ([element isKindOfClass: [iCalEvent class]] &&
|
||||
![(iCalEvent *)element isAllDay] &&
|
||||
![s hasSuffix: @"Z"] &&
|
||||
![s hasSuffix: @"z"])
|
||||
{
|
||||
iCalDateTime *endDate;
|
||||
int delta;
|
||||
|
||||
timezone = [iCalTimeZone timeZoneForName: [[[self->context activeUser] userDefaults] timeZoneName]];
|
||||
[calendar addTimeZone: timezone];
|
||||
|
||||
delta = [[timezone periodForDate: [startDate dateTime]] secondsOffsetFromGMT];
|
||||
event = (iCalEvent *)element;
|
||||
|
||||
[event setStartDate: [[event startDate] dateByAddingYears: 0 months: 0 days: 0 hours: 0 minutes: 0 seconds: -delta]];
|
||||
[startDate setTimeZone: timezone];
|
||||
|
||||
endDate = (iCalDateTime *) [element uniqueChildWithTag: @"dtend"];
|
||||
|
||||
if (endDate)
|
||||
{
|
||||
[event setEndDate: [[event endDate] dateByAddingYears: 0 months: 0 days: 0 hours: 0 minutes: 0 seconds: -delta]];
|
||||
[endDate setTimeZone: timezone];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ([element isKindOfClass: [iCalEvent class]])
|
||||
{
|
||||
event = (iCalEvent *)element;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
Copyright (C) 2007-2011 Inverse inc.
|
||||
Copyright (C) 2007-2012 Inverse inc.
|
||||
Copyright (C) 2004-2005 SKYRIX Software AG
|
||||
|
||||
This file is part of SOGo
|
||||
@@ -456,8 +456,12 @@
|
||||
{
|
||||
SOGoAppointmentFolder *folder;
|
||||
NSCalendarDate *start, *end;
|
||||
NGCalendarDateRange *range;
|
||||
NSMutableArray *fbInfo;
|
||||
int i;
|
||||
NSArray *allOccurences;
|
||||
|
||||
BOOL must_delete;
|
||||
int i, j;
|
||||
|
||||
// We get the start/end date for our conflict range. If the event to be added is recurring, we
|
||||
// check for at least a year to start with.
|
||||
@@ -486,12 +490,50 @@
|
||||
// We first remove any occurences in the freebusy that corresponds to the
|
||||
// current event. We do this to avoid raising a conflict if we move a 1 hour
|
||||
// meeting from 12:00-13:00 to 12:15-13:15. We would overlap on ourself otherwise.
|
||||
//
|
||||
// We must also check here for repetitive events that don't overlap our event.
|
||||
// We remove all events that don't overlap. The events here are already
|
||||
// decomposed.
|
||||
//
|
||||
if ([theEvent isRecurrent])
|
||||
allOccurences = [theEvent recurrenceRangesWithinCalendarDateRange: [NGCalendarDateRange calendarDateRangeWithStartDate: start
|
||||
endDate: end]
|
||||
firstInstanceCalendarDateRange: [NGCalendarDateRange calendarDateRangeWithStartDate: [theEvent startDate]
|
||||
endDate: [theEvent endDate]]];
|
||||
else
|
||||
allOccurences = nil;
|
||||
|
||||
for (i = [fbInfo count]-1; i >= 0; i--)
|
||||
{
|
||||
range = [NGCalendarDateRange calendarDateRangeWithStartDate: [[fbInfo objectAtIndex: i] objectForKey: @"startDate"]
|
||||
endDate: [[fbInfo objectAtIndex: i] objectForKey: @"endDate"]];
|
||||
|
||||
if ([[[fbInfo objectAtIndex: i] objectForKey: @"c_uid"] compare: [theEvent uid]] == NSOrderedSame)
|
||||
[fbInfo removeObjectAtIndex: i];
|
||||
}
|
||||
{
|
||||
[fbInfo removeObjectAtIndex: i];
|
||||
continue;
|
||||
}
|
||||
|
||||
// No need to check if the event isn't recurrent here as it's handled correctly
|
||||
// when we compute the "end" date.
|
||||
if ([allOccurences count])
|
||||
{
|
||||
must_delete = YES;
|
||||
|
||||
for (j = 0; j < [allOccurences count]; j++)
|
||||
{
|
||||
if ([range doesIntersectWithDateRange: [allOccurences objectAtIndex: j]])
|
||||
{
|
||||
must_delete = NO;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (must_delete)
|
||||
[fbInfo removeObjectAtIndex: i];
|
||||
}
|
||||
}
|
||||
|
||||
if ([fbInfo count])
|
||||
{
|
||||
// If we always force the auto-accept if numberOfSimultaneousBookings == 0 (ie., no limit
|
||||
@@ -1714,15 +1756,25 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent
|
||||
{
|
||||
iCalCalendar *calendar;
|
||||
SOGoUser *ownerUser;
|
||||
iCalEvent *event;
|
||||
iCalEvent *event, *conflictingEvent;
|
||||
|
||||
NSString *eventUID;
|
||||
BOOL scheduling;
|
||||
|
||||
calendar = [iCalCalendar parseSingleFromSource: [rq contentAsString]];
|
||||
|
||||
event = [[calendar events] objectAtIndex: 0];
|
||||
eventUID = [event uid];
|
||||
ownerUser = [SOGoUser userWithLogin: owner];
|
||||
scheduling = [self _shouldScheduleEvent: [event organizer]];
|
||||
|
||||
// make sure eventUID doesn't conflict with an existing event - see bug #1853
|
||||
// TODO: send out a no-uid-conflict (DAV:href) xml element (rfc4791 section 5.3.2.1)
|
||||
if (conflictingEvent = [container resourceNameForEventUID: eventUID])
|
||||
{
|
||||
NSString *reason = [NSString stringWithFormat: @"Event UID already in use. (%s)", eventUID];
|
||||
return [NSException exceptionWithHTTPStatus:403 reason: reason];
|
||||
}
|
||||
|
||||
//
|
||||
// New event and we're the organizer -- send invitation to all attendees
|
||||
|
||||
@@ -516,19 +516,23 @@ static inline BOOL _occurenceHasID (iCalRepeatableEntityObject *occurence,
|
||||
//
|
||||
// Returs "YES" if a a group was decomposed among attendees.
|
||||
//
|
||||
// It can also return yes if an attendee was found in the list
|
||||
// matching the organizer. In which case, it was removed.
|
||||
//
|
||||
- (BOOL) expandGroupsInEvent: (iCalEvent *) theEvent
|
||||
{
|
||||
NSMutableArray *allAttendees;
|
||||
NSEnumerator *enumerator;
|
||||
NSString *organizerEmail, *domain;
|
||||
NSMutableArray *allAttendees;
|
||||
iCalPerson *currentAttendee;
|
||||
NSEnumerator *enumerator;
|
||||
SOGoGroup *group;
|
||||
BOOL doesIncludeGroup;
|
||||
|
||||
BOOL eventWasModified;
|
||||
unsigned int i;
|
||||
|
||||
domain = [[context activeUser] domain];
|
||||
organizerEmail = [[theEvent organizer] rfc822Email];
|
||||
doesIncludeGroup = NO;
|
||||
eventWasModified = NO;
|
||||
allAttendees = [NSMutableArray arrayWithArray: [theEvent attendees]];
|
||||
enumerator = [[theEvent attendees] objectEnumerator];
|
||||
while ((currentAttendee = [enumerator nextObject]))
|
||||
@@ -548,7 +552,7 @@ static inline BOOL _occurenceHasID (iCalRepeatableEntityObject *occurence,
|
||||
for (i = 0; i < [members count]; i++)
|
||||
{
|
||||
user = [members objectAtIndex: i];
|
||||
doesIncludeGroup = YES;
|
||||
eventWasModified = YES;
|
||||
|
||||
// If the organizer is part of the group, we skip it from
|
||||
// the addition to the attendees' list
|
||||
@@ -565,12 +569,23 @@ static inline BOOL _occurenceHasID (iCalRepeatableEntityObject *occurence,
|
||||
[allAttendees addObject: person];
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// We remove any attendees matching the organizer. Apple iCal will do that when
|
||||
// you invite someone. It'll add the organizer in the attendee list, which will
|
||||
// confuse itself!
|
||||
if ([[currentAttendee rfc822Email] caseInsensitiveCompare: organizerEmail] == NSOrderedSame)
|
||||
{
|
||||
[allAttendees removeObject: currentAttendee];
|
||||
eventWasModified = YES;
|
||||
}
|
||||
}
|
||||
} // while (currentAttendee ...
|
||||
|
||||
if (doesIncludeGroup)
|
||||
if (eventWasModified)
|
||||
[theEvent setAttendees: allAttendees];
|
||||
|
||||
return doesIncludeGroup;
|
||||
return eventWasModified;
|
||||
}
|
||||
|
||||
- (void) _updateRecurrenceIDsWithEvent: (iCalRepeatableEntityObject*) newEvent
|
||||
|
||||
@@ -70,4 +70,6 @@
|
||||
|
||||
SOGoReminderEnabled = YES;
|
||||
SOGoRemindWithASound = YES;
|
||||
|
||||
SOGoSearchMinimumWordLength = 2;
|
||||
}
|
||||
|
||||
@@ -77,6 +77,8 @@
|
||||
|
||||
- (BOOL) hideSystemEMail;
|
||||
|
||||
- (int) searchMinimumWordLength;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* SOGODOMAINDEFAULTS_H */
|
||||
|
||||
@@ -319,4 +319,9 @@
|
||||
return [self boolForKey: @"SOGoHideSystemEMail"];
|
||||
}
|
||||
|
||||
- (int) searchMinimumWordLength
|
||||
{
|
||||
return [self integerForKey: @"SOGoSearchMinimumWordLength"];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user