Monotone-Parent: 463195ab0268a4a769eab22f23b6aecf0c87ad79

Monotone-Revision: 9abbb51cbabcad645190865841814453369fa85f

Monotone-Author: wsourdeau@inverse.ca
Monotone-Date: 2007-11-18T10:16:25
Monotone-Branch: ca.inverse.sogo
This commit is contained in:
Wolfgang Sourdeau
2007-11-18 10:16:25 +00:00
parent e3cdb8ecbf
commit 73bfada6bf
50 changed files with 1751 additions and 1265 deletions
@@ -19,6 +19,7 @@ Attendees = "Attendees";
request_info = "invites you to participate in a meeting.";
"Add to calendar" = "Add to calendar";
"Delete from calendar" = "Delete from calendar";
"Update status" = "Update status";
Accept = "Accept";
Decline = "Decline";
Tentative = "Tentative";
@@ -19,6 +19,7 @@ Attendees = "Invités";
request_info = "vous invite à une réunion.";
"Add to calendar" = "Ajouter à l'agenda";
"Delete from calendar" = "Effacer de l'agenda";
"Update status" = "Intégrer les modifications";
Accept = "Accepter";
Decline = "Decliner";
Tentative = "Tentative";
@@ -19,6 +19,7 @@ Attendees = "Attendees";
request_info = "invites you to participate in a meeting.";
"Add to calendar" = "Add to calendar";
"Delete from calendar" = "Delete from calendar";
"Update status" = "Update status";
Accept = "Accept";
Decline = "Decline";
Tentative = "Tentative";
+141 -7
View File
@@ -26,12 +26,17 @@
#import <NGObjWeb/WOResponse.h>
#import <NGCards/iCalCalendar.h>
#import <NGCards/iCalEvent.h>
#import <NGCards/iCalPerson.h>
#import <UI/Common/WODirectAction+SOGo.h>
#import <NGImap4/NGImap4EnvelopeAddress.h>
#import <SoObjects/Appointments/iCalPerson+SOGo.h>
#import <SoObjects/Appointments/SOGoAppointmentObject.h>
#import <SoObjects/Appointments/SOGoAppointmentFolder.h>
#import <SoObjects/Mailer/SOGoMailObject.h>
#import <SoObjects/SOGo/SOGoUser.h>
#import <SoObjects/SOGo/iCalEntityObject+Utilities.h>
#import <SoObjects/Mailer/SOGoMailBodyPart.h>
@@ -58,12 +63,12 @@
}
- (SOGoAppointmentObject *) _eventObjectWithUID: (NSString *) uid
forUser: (SOGoUser *) user
{
SOGoAppointmentFolder *personalFolder;
SOGoAppointmentObject *eventObject;
personalFolder
= [[context activeUser] personalCalendarFolderInContext: context];
personalFolder = [user personalCalendarFolderInContext: context];
eventObject = [personalFolder lookupName: uid
inContext: context acquire: NO];
if (![eventObject isKindOfClass: [SOGoAppointmentObject class]])
@@ -73,6 +78,11 @@
return eventObject;
}
- (SOGoAppointmentObject *) _eventObjectWithUID: (NSString *) uid
{
return [self _eventObjectWithUID: uid forUser: [context activeUser]];
}
- (iCalEvent *)
_setupChosenEventAndEventObject: (SOGoAppointmentObject **) eventObject
{
@@ -86,7 +96,7 @@
chosenEvent = emailEvent;
else
{
calendarEvent = (iCalEvent *) [*eventObject component: NO];
calendarEvent = (iCalEvent *) [*eventObject component: NO secure: NO];
if ([calendarEvent compare: emailEvent] == NSOrderedAscending)
chosenEvent = emailEvent;
else
@@ -99,14 +109,42 @@
return chosenEvent;
}
#warning this is code copied from SOGoAppointmentObject...
- (void) _updateAttendee: (iCalPerson *) attendee
withSequence: (NSNumber *) sequence
andCalUID: (NSString *) calUID
forUID: (NSString *) uid
{
SOGoAppointmentObject *eventObject;
iCalEvent *event;
iCalPerson *otherAttendee;
NSString *iCalString;
eventObject = [self _eventObjectWithUID: calUID
forUser: [SOGoUser userWithLogin: uid roles: nil]];
if (![eventObject isNew])
{
event = [eventObject component: NO secure: NO];
if ([[event sequence] compare: sequence]
== NSOrderedSame)
{
otherAttendee
= [event findParticipantWithEmail: [attendee rfc822Email]];
[otherAttendee setPartStat: [attendee partStat]];
iCalString = [[event parent] versitString];
[eventObject saveContentString: iCalString];
}
}
}
- (WOResponse *) _changePartStatusAction: (NSString *) newStatus
{
WOResponse *response;
SOGoAppointmentObject *eventObject;
iCalEvent *chosenEvent;
iCalPerson *user;
iCalCalendar *calendar;
NSString *rsvp, *method;
iCalCalendar *emailCalendar, *calendar;
NSString *rsvp, *method, *organizerUID;
chosenEvent = [self _setupChosenEventAndEventObject: &eventObject];
if (chosenEvent)
@@ -114,7 +152,8 @@
user = [chosenEvent findParticipant: [context activeUser]];
[user setPartStat: newStatus];
calendar = [chosenEvent parent];
method = [[calendar method] lowercaseString];
emailCalendar = [[self _emailEvent] parent];
method = [[emailCalendar method] lowercaseString];
if ([method isEqualToString: @"request"])
{
[calendar setMethod: @""];
@@ -123,8 +162,12 @@
else
rsvp = nil;
[eventObject saveContentString: [calendar versitString]];
if (rsvp && [rsvp isEqualToString: @"true"])
if ([rsvp isEqualToString: @"true"])
[eventObject sendResponseToOrganizer];
organizerUID = [[chosenEvent organizer] uid];
if (organizerUID)
[self _updateAttendee: user withSequence: [chosenEvent sequence]
andCalUID: [chosenEvent uid] forUID: organizerUID];
response = [self responseWith204];
}
else
@@ -146,6 +189,97 @@
return [self _changePartStatusAction: @"DECLINED"];
}
- (WOResponse *) deleteFromCalendarAction
{
iCalEvent *emailEvent;
SOGoAppointmentObject *eventObject;
WOResponse *response;
emailEvent = [self _emailEvent];
if (emailEvent)
{
eventObject = [self _eventObjectWithUID: [emailEvent uid]];
response = [self responseWith204];
}
else
{
response = [context response];
[response setStatus: 409];
}
return response;
}
- (iCalPerson *) _emailParticipantWithEvent: (iCalEvent *) event
{
NSString *emailFrom;
SOGoMailObject *mailObject;
NGImap4EnvelopeAddress *address;
mailObject = [[self clientObject] mailObject];
address = [[mailObject fromEnvelopeAddresses] objectAtIndex: 0];
emailFrom = [address baseEMail];
return [event findParticipantWithEmail: emailFrom];
}
- (BOOL) _updateParticipantStatusInEvent: (iCalEvent *) calendarEvent
fromEvent: (iCalEvent *) emailEvent
inObject: (SOGoAppointmentObject *) eventObject
{
iCalPerson *calendarParticipant, *mailParticipant;
NSString *partStat;
BOOL result;
calendarParticipant = [self _emailParticipantWithEvent: calendarEvent];
mailParticipant = [self _emailParticipantWithEvent: emailEvent];
if (calendarParticipant && mailParticipant)
{
result = YES;
partStat = [mailParticipant partStat];
if ([partStat caseInsensitiveCompare: [calendarParticipant partStat]]
!= NSOrderedSame)
{
[calendarParticipant setPartStat: [partStat uppercaseString]];
[eventObject saveComponent: calendarEvent];
}
}
else
result = NO;
return result;
}
- (WOResponse *) updateUserStatusAction
{
iCalEvent *emailEvent, *calendarEvent;
SOGoAppointmentObject *eventObject;
WOResponse *response;
response = nil;
emailEvent = [self _emailEvent];
if (emailEvent)
{
eventObject = [self _eventObjectWithUID: [emailEvent uid]];
calendarEvent = [eventObject component: NO secure: NO];
if (([[emailEvent sequence] compare: [calendarEvent sequence]]
!= NSOrderedDescending)
&& ([self _updateParticipantStatusInEvent: calendarEvent
fromEvent: emailEvent
inObject: eventObject]))
response = [self responseWith204];
}
if (!response)
{
response = [context response];
[response setStatus: 409];
}
return response;
}
// - (WOResponse *) markTentativeAction
// {
// return [self _changePartStatusAction: @"TENTATIVE"];
+4 -2
View File
@@ -24,10 +24,12 @@
#import "UIxMailPartViewer.h"
@class SOGoDateFormatter;
@class iCalEvent;
@class iCalCalendar;
@class SOGoAppointmentObject;
@class SOGoDateFormatter;
@interface UIxMailPartICalViewer : UIxMailPartViewer
{
iCalCalendar *inCalendar;
@@ -35,7 +37,7 @@
id attendee;
SOGoDateFormatter *dateFormatter;
id item;
id storedEventObject;
SOGoAppointmentObject *storedEventObject;
iCalEvent *storedEvent;
}
+82 -66
View File
@@ -28,7 +28,6 @@
#import <NGObjWeb/WOResponse.h>
#import <NGExtensions/NSCalendarDate+misc.h>
#import <NGExtensions/NSNull+misc.h>
#import <NGExtensions/NSObject+Logs.h>
#import <NGImap4/NGImap4EnvelopeAddress.h>
@@ -40,9 +39,11 @@
#import <SoObjects/SOGo/SOGoDateFormatter.h>
#import <SoObjects/SOGo/SOGoUser.h>
#import <SoObjects/Appointments/iCalEntityObject+SOGo.h>
#import <SoObjects/Appointments/SOGoAppointmentFolder.h>
#import <SoObjects/Appointments/SOGoAppointmentObject.h>
#import <SoObjects/Mailer/SOGoMailObject.h>
#import <SoObjects/Mailer/SOGoMailBodyPart.h>
#import "UIxMailPartICalViewer.h"
@@ -109,35 +110,32 @@
- (BOOL) couldParseCalendar
{
return [[self inCalendar] isNotNull];
return (([self inCalendar]));
}
- (iCalEvent *) inEvent
{
NSArray *events;
if (inEvent)
return [inEvent isNotNull] ? inEvent : nil;
events = [[self inCalendar] events];
if ([events count] > 0) {
inEvent = [[events objectAtIndex:0] retain];
return inEvent;
}
else {
inEvent = [[NSNull null] retain];
return nil;
}
if (!inEvent)
{
events = [[self inCalendar] events];
if ([events count] > 0)
inEvent = [[events objectAtIndex:0] retain];
}
return inEvent;
}
/* formatters */
- (SOGoDateFormatter *) dateFormatter
{
if (dateFormatter == nil) {
dateFormatter = [[context activeUser] dateFormatterInContext: context];
[dateFormatter retain];
}
if (!dateFormatter)
{
dateFormatter = [[context activeUser] dateFormatterInContext: context];
[dateFormatter retain];
}
return dateFormatter;
}
@@ -146,7 +144,7 @@
- (void) setAttendee: (id) _attendee
{
ASSIGN(attendee, _attendee);
ASSIGN (attendee, _attendee);
}
- (id) attendee
@@ -220,7 +218,7 @@
/* calendar folder support */
- (id) calendarFolder
- (SOGoAppointmentFolder *) calendarFolder
{
/* return scheduling calendar of currently logged-in user */
SOGoUser *user;
@@ -234,49 +232,50 @@
return [folder lookupName: @"personal" inContext: context acquire: NO];
}
- (id) storedEventObject
- (SOGoAppointmentObject *) storedEventObject
{
/* lookup object in the users Calendar */
id calendar;
SOGoAppointmentFolder *calendar;
NSString *filename;
if (storedEventObject)
return [storedEventObject isNotNull] ? storedEventObject : nil;
calendar = [self calendarFolder];
if ([calendar isKindOfClass:[NSException class]]) {
[self errorWithFormat:@"Did not find Calendar folder: %@", calendar];
}
else {
NSString *filename;
filename = [calendar resourceNameForEventUID:[[self inEvent] uid]];
if (filename) {
// TODO: When we get an exception, this might be an auth issue meaning
// that the UID indeed exists but that the user has no access to
// the object.
// Of course this is quite unusual for the private calendar though.
id tmp;
tmp = [calendar lookupName:filename inContext:[self context] acquire:NO];
if ([tmp isNotNull] && ![tmp isKindOfClass:[NSException class]])
storedEventObject = [tmp retain];
if (!storedEventObject)
{
calendar = [self calendarFolder];
if ([calendar isKindOfClass: [NSException class]])
[self errorWithFormat:@"Did not find Calendar folder: %@", calendar];
else
{
filename = [calendar resourceNameForEventUID:[[self inEvent] uid]];
if (filename)
{
storedEventObject = [calendar lookupName: filename
inContext: [self context]
acquire: NO];
if ([storedEventObject isKindOfClass: [NSException class]])
storedEventObject = nil;
else
[storedEventObject retain];
}
}
}
}
if (storedEventObject == nil)
storedEventObject = [[NSNull null] retain];
return storedEventObject;
}
- (BOOL) isEventStoredInCalendar
{
return [[self storedEventObject] isNotNull];
return (([self storedEventObject]));
}
- (iCalEvent *) storedEvent
{
return (iCalEvent *) [(SOGoAppointmentObject *)[self storedEventObject] component: NO];
if (!storedEvent)
{
storedEvent = [[self storedEventObject] component: NO secure: NO];
[storedEvent retain];
}
return storedEvent;
}
/* organizer tracking */
@@ -294,34 +293,24 @@
{
iCalEvent *authorativeEvent;
if ([[self storedEvent] compare: [self inEvent]]
== NSOrderedAscending)
[self storedEvent];
if (!storedEvent
|| ([storedEvent compare: [self inEvent]] == NSOrderedAscending))
authorativeEvent = inEvent;
else
authorativeEvent = storedEventObject;
authorativeEvent = [self storedEvent];
return authorativeEvent;
}
- (BOOL) isLoggedInUserTheOrganizer
{
iCalPerson *organizer;
organizer = [[self authorativeEvent] organizer];
return [[context activeUser] hasEmail: [organizer rfc822Email]];
return [[self authorativeEvent] userIsOrganizer: [context activeUser]];
}
- (BOOL) isLoggedInUserAnAttendee
{
NSString *loginEMail;
if ((loginEMail = [self loggedInUserEMail]) == nil) {
[self warnWithFormat:@"Could not determine email of logged in user?"];
return NO;
}
return [[self authorativeEvent] isParticipant:loginEMail];
return [[self authorativeEvent] userIsParticipant: [context activeUser]];
}
/* derived fields */
@@ -405,7 +394,34 @@
- (BOOL) isReplySenderAnAttendee
{
return [[self storedReplyAttendee] isNotNull];
return (([self storedReplyAttendee]));
}
- (iCalPerson *) _emailParticipantWithEvent: (iCalEvent *) event
{
NSString *emailFrom;
SOGoMailObject *mailObject;
NGImap4EnvelopeAddress *address;
mailObject = [[self clientObject] mailObject];
address = [[mailObject fromEnvelopeAddresses] objectAtIndex: 0];
emailFrom = [address baseEMail];
return [event findParticipantWithEmail: emailFrom];
}
- (BOOL) hasSenderStatusChanged
{
iCalPerson *emailParticipant, *calendarParticipant;
[self inEvent];
[self storedEvent];
emailParticipant = [self _emailParticipantWithEvent: inEvent];
calendarParticipant = [self _emailParticipantWithEvent: storedEvent];
return ([[emailParticipant partStat]
caseInsensitiveCompare: [calendarParticipant partStat]]
!= NSOrderedSame);
}
@end /* UIxMailPartICalViewer */
+7 -2
View File
@@ -20,6 +20,11 @@
actionClass = "UIxMailPartICalActions";
actionName = "decline";
};
updateUserStatus = {
protectedBy = "View";
actionClass = "UIxMailPartICalActions";
actionName = "updateUserStatus";
};
/* tentative = {
protectedBy = "View";
actionClass = "UIxMailPartICalAction";
@@ -29,12 +34,12 @@
protectedBy = "View";
actionClass = "UIxMailPartICalAction";
actionName = "addToCalendar";
};
}; */
deleteFromCalendar = {
protectedBy = "View";
actionClass = "UIxMailPartICalAction";
actionName = "deleteFromCalendar";
}; */
};
};
};
};