Monotone-Parent: a164259525f718f804b625a9f09b4c3b3c9e83f8
Monotone-Revision: 11f4bdac420d36e45b12ca5d1d393ec34f43c609 Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2007-11-10T00:02:30 Monotone-Branch: ca.inverse.sogo
This commit is contained in:
parent
aebac17d01
commit
1eda040e84
16
ChangeLog
16
ChangeLog
|
@ -1,5 +1,21 @@
|
|||
2007-11-09 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* UI/MailPartViewers/UIxMailPartICalViewer.m
|
||||
([UIxMailPartICalViewer -acceptLink])
|
||||
([UIxMailPartICalViewer -declineLink])
|
||||
([UIxMailPartICalViewer -tentativeLink]): removed useless methods.
|
||||
|
||||
* UI/MailPartViewers/UIxMailPartICalAction.m ([UIxMailPartICalAction -addToCalendarAction])
|
||||
([UIxMailPartICalAction -deleteFromCalendarAction]): new stub
|
||||
methods.
|
||||
|
||||
* SoObjects/Mailer/SOGoMailObject.m ([SOGoMailObject
|
||||
-lookupImap4BodyPartKey:]): make use of the new method below.
|
||||
|
||||
* SoObjects/Mailer/SOGoMailBodyPart.m ([SOGoMailBodyPart
|
||||
+bodyPartClassForMimeType:mimeTypeinContext:_ctx]): new method
|
||||
that returns an appropriate Class depending on a given mime type.
|
||||
|
||||
* UI/SOGoUI/UIxComponent.m ([UIxComponent -canCreateOrModify]):
|
||||
new boolean accessor that determines whether someone can create
|
||||
(i.e. modify a new entry) or modify an existing entry.
|
||||
|
|
|
@ -62,6 +62,8 @@
|
|||
|
||||
+ (Class) bodyPartClassForKey: (NSString *) _key
|
||||
inContext: (id) _ctx;
|
||||
+ (Class) bodyPartClassForMimeType: (NSString *) mimeType
|
||||
inContext: (id) _ctx;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -34,6 +34,8 @@
|
|||
#import <NGExtensions/NGBase64Coding.h>
|
||||
#import <NGImap4/NGImap4Connection.h>
|
||||
|
||||
#import <SoObjects/SOGo/NSDictionary+Utilities.h>
|
||||
|
||||
#import "SOGoMailObject.h"
|
||||
#import "SOGoMailManager.h"
|
||||
|
||||
|
@ -305,7 +307,9 @@ static BOOL debugOn = NO;
|
|||
|
||||
/* factory */
|
||||
|
||||
+ (Class)bodyPartClassForKey:(NSString *)_key inContext:(id)_ctx {
|
||||
+ (Class) bodyPartClassForKey: (NSString *) _key
|
||||
inContext: (id) _ctx
|
||||
{
|
||||
NSString *pe;
|
||||
|
||||
pe = [_key pathExtension];
|
||||
|
@ -335,6 +339,36 @@ static BOOL debugOn = NO;
|
|||
return self;
|
||||
}
|
||||
|
||||
+ (Class) bodyPartClassForMimeType: (NSString *) mimeType
|
||||
inContext: (id) _ctx
|
||||
{
|
||||
NSString *classString;
|
||||
Class klazz;
|
||||
|
||||
if ([mimeType isEqualToString: @"image/gif"]
|
||||
|| [mimeType isEqualToString: @"image/png"]
|
||||
|| [mimeType isEqualToString: @"image/jpg"])
|
||||
classString = @"SOGoImageMailBodyPart";
|
||||
else if ([mimeType isEqualToString: @"text/calendar"])
|
||||
classString = @"SOGoCalendarMailBodyPart";
|
||||
else if ([mimeType isEqualToString: @"text/x-vcard"])
|
||||
classString = @"SOGoVCardMailBodyPart";
|
||||
else if ([mimeType isEqualToString: @"message/rfc822"])
|
||||
classString = @"SOGoMessageMailBodyPart";
|
||||
else
|
||||
{
|
||||
NSLog (@"unhandled mime type: '%@'", mimeType);
|
||||
classString = nil;
|
||||
}
|
||||
|
||||
if (classString)
|
||||
klazz = NSClassFromString (classString);
|
||||
else
|
||||
klazz = Nil;
|
||||
|
||||
return klazz;
|
||||
}
|
||||
|
||||
/* etag support */
|
||||
|
||||
- (id)davEntityTag {
|
||||
|
|
|
@ -735,8 +735,22 @@ static BOOL debugSoParts = NO;
|
|||
{
|
||||
// TODO: we might want to check for existence prior controller creation
|
||||
Class clazz;
|
||||
NSArray *parts;
|
||||
int part;
|
||||
NSDictionary *partDesc;
|
||||
NSString *mimeType;
|
||||
|
||||
clazz = [SOGoMailBodyPart bodyPartClassForKey:_key inContext:_ctx];
|
||||
parts = [[self bodyStructure] objectForKey: @"parts"];
|
||||
part = [_key intValue] - 1;
|
||||
if (part > -1 && part < [parts count])
|
||||
{
|
||||
partDesc = [parts objectAtIndex: part];
|
||||
mimeType = [[partDesc keysWithFormat: @"%{type}/%{subtype}"] lowercaseString];
|
||||
clazz = [SOGoMailBodyPart bodyPartClassForMimeType: mimeType
|
||||
inContext: _ctx];
|
||||
}
|
||||
else
|
||||
clazz = Nil;
|
||||
|
||||
return [clazz objectWithName:_key inContainer: self];
|
||||
}
|
||||
|
|
|
@ -17,15 +17,17 @@ Organizer = "Organisateur";
|
|||
Time = "Time";
|
||||
Attendees = "Attendees";
|
||||
request_info = "invites you to participate in a meeting.";
|
||||
do_add_to_cal = "add to calendar";
|
||||
do_del_from_cal = "delete from calendar";
|
||||
do_accept = "accept";
|
||||
do_decline = "decline";
|
||||
do_tentative = "tentative";
|
||||
do_update_status = "update status in calendar";
|
||||
"Add to calendar" = "Add to calendar";
|
||||
"Delete from calendar" = "Delete from calendar";
|
||||
Accept = "Accept";
|
||||
Decline = "Decline";
|
||||
Tentative = "Tentative";
|
||||
"Update status in calendar" = "Update status in calendar";
|
||||
reply_info_no_attendee = "You received a reply to a scheduling event but the sender of the reply is not a participant.";
|
||||
reply_info = "This is a reply to an event invitation done by you.";
|
||||
|
||||
"to" = "to";
|
||||
|
||||
"Untitled" = "Untitled";
|
||||
|
||||
"Size" = "Size";
|
||||
|
|
|
@ -17,15 +17,17 @@ Organizer = "Organisateur";
|
|||
Time = "Date";
|
||||
Attendees = "Invités";
|
||||
request_info = "vous invite à une réunion.";
|
||||
do_add_to_cal = "ajouter à l'agenda";
|
||||
do_del_from_cal = "effacer de l'agenda";
|
||||
do_accept = "accepter";
|
||||
do_decline = "decliner";
|
||||
do_tentative = "tentative";
|
||||
do_update_status = "mettre l'agenda à jour";
|
||||
"Add to calendar" = "Ajouter à l'agenda";
|
||||
"Delete from calendar" = "Effacer de l'agenda";
|
||||
Accept = "Accepter";
|
||||
Decline = "Decliner";
|
||||
Tentative = "Tentative";
|
||||
"Update status in calendar" = "Mettre l'agenda à jour";
|
||||
reply_info_no_attendee = "Vous avez reçu une réponse à un événement mais l'expéditeur n'est pas un invité.";
|
||||
reply_info = "Ceci est une réponse à un événement que vous avez organisé.";
|
||||
|
||||
"to" = "à";
|
||||
|
||||
"Untitled" = "Sans titre";
|
||||
|
||||
"Size" = "Taille";
|
||||
|
|
|
@ -17,15 +17,17 @@ Organizer = "Organisateur";
|
|||
Time = "Time";
|
||||
Attendees = "Attendees";
|
||||
request_info = "invites you to participate in a meeting.";
|
||||
do_add_to_cal = "add to calendar";
|
||||
do_del_from_cal = "delete from calendar";
|
||||
do_accept = "accept";
|
||||
do_decline = "decline";
|
||||
do_tentative = "tentative";
|
||||
do_update_status = "update status in calendar";
|
||||
"Add to calendar" = "Add to calendar";
|
||||
"Delete from calendar" = "Delete from calendar";
|
||||
Accept = "Accept";
|
||||
Decline = "Decline";
|
||||
Tentative = "Tentative";
|
||||
"Update status in calendar" = "Update status in calendar";
|
||||
reply_info_no_attendee = "You received a reply to a scheduling event but the sender of the reply is not a participant.";
|
||||
reply_info = "This is a reply to an event invitation done by you.";
|
||||
|
||||
"to" = "to";
|
||||
|
||||
"Untitled" = "Untitled";
|
||||
|
||||
"Size" = "Size";
|
||||
|
|
|
@ -1,76 +1,63 @@
|
|||
/*
|
||||
Copyright (C) 2005 SKYRIX Software AG
|
||||
|
||||
This file is part of OpenGroupware.org.
|
||||
|
||||
OGo is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License as published by the
|
||||
Free Software Foundation; either version 2, or (at your option) any
|
||||
later version.
|
||||
|
||||
OGo 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 Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with OGo; see the file COPYING. If not, write to the
|
||||
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
02111-1307, USA.
|
||||
/* UIxMailPartICalAction.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2007 Inverse groupe conseil
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@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 <NGObjWeb/SoObject.h>
|
||||
#import <NGObjWeb/WOContext.h>
|
||||
#import <NGObjWeb/WOResponse.h>
|
||||
#import <Foundation/NSString.h>
|
||||
#import <NGObjWeb/WODirectAction.h>
|
||||
#import <NGExtensions/NSNull+misc.h>
|
||||
#import <NGExtensions/NSString+misc.h>
|
||||
|
||||
#import <UI/Common/WODirectAction+SOGo.h>
|
||||
|
||||
@interface UIxMailPartICalAction : WODirectAction
|
||||
@end
|
||||
|
||||
@implementation UIxMailPartICalAction
|
||||
|
||||
- (id)redirectToViewerWithError:(NSString *)_error {
|
||||
WOResponse *r;
|
||||
NSString *viewURL;
|
||||
id mail;
|
||||
|
||||
mail = [[self clientObject] valueForKey:@"mailObject"];
|
||||
[self logWithFormat:@"MAIL: %@", mail];
|
||||
|
||||
viewURL = [mail baseURLInContext:[self context]];
|
||||
[self logWithFormat:@" url: %@", viewURL];
|
||||
|
||||
viewURL = [viewURL stringByAppendingString:
|
||||
[viewURL hasSuffix:@"/"] ? @"view" : @"/view"];
|
||||
|
||||
if ([_error isNotNull] && [_error length] > 0) {
|
||||
viewURL = [viewURL stringByAppendingString:@"?error="];
|
||||
viewURL = [viewURL stringByAppendingString:
|
||||
[_error stringByEscapingURL]];
|
||||
- (WOResponse *) _changePartStatusAction: (NSString *) _newStatus
|
||||
{
|
||||
return [self responseWithStatus: 404];
|
||||
}
|
||||
|
||||
r = [[self context] response];
|
||||
[r setStatus:302 /* moved */];
|
||||
[r setHeader:viewURL forKey:@"location"];
|
||||
return r;
|
||||
- (WOResponse *) markAcceptedAction
|
||||
{
|
||||
return [self _changePartStatusAction: @"ACCEPTED"];
|
||||
}
|
||||
|
||||
- (id)changePartStatusAction:(NSString *)_newStatus {
|
||||
[self logWithFormat:@"TODO: should %@: %@", _newStatus, [self clientObject]];
|
||||
return [self redirectToViewerWithError:
|
||||
[_newStatus stringByAppendingString:@" not implemented!"]];
|
||||
- (WOResponse *) markDeclinedAction
|
||||
{
|
||||
return [self _changePartStatusAction: @"DECLINED"];
|
||||
}
|
||||
|
||||
- (id)markAcceptedAction {
|
||||
return [self changePartStatusAction:@"ACCEPTED"];
|
||||
- (WOResponse *) markTentativeAction
|
||||
{
|
||||
return [self _changePartStatusAction: @"TENTATIVE"];
|
||||
}
|
||||
- (id)markDeclinedAction {
|
||||
return [self changePartStatusAction:@"DECLINED"];
|
||||
|
||||
- (WOResponse *) addToCalendarAction
|
||||
{
|
||||
return [self responseWithStatus: 404];
|
||||
}
|
||||
- (id)markTentativeAction {
|
||||
return [self changePartStatusAction:@"TENTATIVE"];
|
||||
|
||||
- (WOResponse *) deleteFromCalendarAction
|
||||
{
|
||||
return [self responseWithStatus: 404];
|
||||
}
|
||||
|
||||
@end /* UIxMailPartICalAction */
|
||||
|
|
|
@ -46,34 +46,37 @@
|
|||
|
||||
@implementation UIxMailPartICalViewer
|
||||
|
||||
- (void)dealloc {
|
||||
[self->storedEventObject release];
|
||||
[self->storedEvent release];
|
||||
[self->attendee release];
|
||||
[self->item release];
|
||||
[self->inCalendar release];
|
||||
[self->inEvent release];
|
||||
[self->dateFormatter release];
|
||||
- (void) dealloc
|
||||
{
|
||||
[storedEventObject release];
|
||||
[storedEvent release];
|
||||
[attendee release];
|
||||
[item release];
|
||||
[inCalendar release];
|
||||
[inEvent release];
|
||||
[dateFormatter release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
/* maintain caches */
|
||||
|
||||
- (void)resetPathCaches {
|
||||
- (void) resetPathCaches
|
||||
{
|
||||
[super resetPathCaches];
|
||||
[self->inEvent release]; self->inEvent = nil;
|
||||
[self->inCalendar release]; self->inCalendar = nil;
|
||||
[self->storedEventObject release]; self->storedEventObject = nil;
|
||||
[self->storedEvent release]; self->storedEvent = nil;
|
||||
[inEvent release]; inEvent = nil;
|
||||
[inCalendar release]; inCalendar = nil;
|
||||
[storedEventObject release]; storedEventObject = nil;
|
||||
[storedEvent release]; storedEvent = nil;
|
||||
|
||||
/* not strictly path-related, but useless without it anyway: */
|
||||
[self->attendee release]; self->attendee = nil;
|
||||
[self->item release]; self->item = nil;
|
||||
[attendee release]; attendee = nil;
|
||||
[item release]; item = nil;
|
||||
}
|
||||
|
||||
/* raw content handling */
|
||||
|
||||
- (NSStringEncoding)fallbackStringEncoding {
|
||||
- (NSStringEncoding) fallbackStringEncoding
|
||||
{
|
||||
/*
|
||||
iCalendar invitations sent by Outlook 2002 have the annoying bug that the
|
||||
mail states an UTF-8 content encoding but the actual iCalendar content is
|
||||
|
@ -102,52 +105,66 @@
|
|||
return inCalendar;
|
||||
}
|
||||
|
||||
- (BOOL)couldParseCalendar {
|
||||
- (BOOL) couldParseCalendar
|
||||
{
|
||||
return [[self inCalendar] isNotNull];
|
||||
}
|
||||
|
||||
- (iCalEvent *)inEvent {
|
||||
- (iCalEvent *) inEvent
|
||||
{
|
||||
NSArray *events;
|
||||
|
||||
if (self->inEvent != nil)
|
||||
return [self->inEvent isNotNull] ? self->inEvent : nil;
|
||||
if (inEvent)
|
||||
return [inEvent isNotNull] ? inEvent : nil;
|
||||
|
||||
events = [[self inCalendar] events];
|
||||
if ([events count] > 0) {
|
||||
self->inEvent = [[events objectAtIndex:0] retain];
|
||||
return self->inEvent;
|
||||
inEvent = [[events objectAtIndex:0] retain];
|
||||
return inEvent;
|
||||
}
|
||||
else {
|
||||
self->inEvent = [[NSNull null] retain];
|
||||
inEvent = [[NSNull null] retain];
|
||||
return nil;
|
||||
}
|
||||
}
|
||||
|
||||
/* formatters */
|
||||
|
||||
- (SOGoDateFormatter *)dateFormatter {
|
||||
if (self->dateFormatter == nil) {
|
||||
- (SOGoDateFormatter *) dateFormatter
|
||||
{
|
||||
if (dateFormatter == nil) {
|
||||
dateFormatter = [[context activeUser] dateFormatterInContext: context];
|
||||
[dateFormatter retain];
|
||||
}
|
||||
|
||||
return self->dateFormatter;
|
||||
return dateFormatter;
|
||||
}
|
||||
|
||||
/* below is copied from UIxAppointmentView, can we avoid that? */
|
||||
|
||||
- (void)setAttendee:(id)_attendee {
|
||||
ASSIGN(self->attendee, _attendee);
|
||||
- (void) setAttendee: (id) _attendee
|
||||
{
|
||||
ASSIGN(attendee, _attendee);
|
||||
}
|
||||
- (id)attendee {
|
||||
return self->attendee;
|
||||
|
||||
- (id) attendee
|
||||
{
|
||||
return attendee;
|
||||
}
|
||||
|
||||
- (NSString *) _personForDisplay: (iCalPerson *) person
|
||||
{
|
||||
return [NSString stringWithFormat: @"%@ <%@>",
|
||||
[person cnWithoutQuotes],
|
||||
[person rfc822Email]];
|
||||
NSString *fn, *email, *result;
|
||||
|
||||
fn = [person cnWithoutQuotes];
|
||||
email = [person rfc822Email];
|
||||
if ([fn length])
|
||||
result = [NSString stringWithFormat: @"%@ <%@>",
|
||||
fn, email];
|
||||
else
|
||||
result = email;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
- (NSString *) attendeeForDisplay
|
||||
|
@ -155,11 +172,14 @@
|
|||
return [self _personForDisplay: attendee];
|
||||
}
|
||||
|
||||
- (void)setItem:(id)_item {
|
||||
ASSIGN(self->item, _item);
|
||||
- (void) setItem: (id) _item
|
||||
{
|
||||
ASSIGN(item, _item);
|
||||
}
|
||||
- (id)item {
|
||||
return self->item;
|
||||
|
||||
- (id) item
|
||||
{
|
||||
return item;
|
||||
}
|
||||
|
||||
- (NSCalendarDate *) startTime
|
||||
|
@ -186,10 +206,13 @@
|
|||
return date;
|
||||
}
|
||||
|
||||
- (BOOL)isEndDateOnSameDay {
|
||||
- (BOOL) isEndDateOnSameDay
|
||||
{
|
||||
return [[self startTime] isDateOnSameDay:[self endTime]];
|
||||
}
|
||||
- (NSTimeInterval)duration {
|
||||
|
||||
- (NSTimeInterval) duration
|
||||
{
|
||||
return [[self endTime] timeIntervalSinceDate:[self startTime]];
|
||||
}
|
||||
|
||||
|
@ -209,12 +232,13 @@
|
|||
return [folder lookupName: @"personal" inContext: context acquire: NO];
|
||||
}
|
||||
|
||||
- (id)storedEventObject {
|
||||
- (id) storedEventObject
|
||||
{
|
||||
/* lookup object in the users Calendar */
|
||||
id calendar;
|
||||
|
||||
if (self->storedEventObject != nil)
|
||||
return [self->storedEventObject isNotNull] ? self->storedEventObject : nil;
|
||||
if (storedEventObject)
|
||||
return [storedEventObject isNotNull] ? storedEventObject : nil;
|
||||
|
||||
calendar = [self calendarFolder];
|
||||
if ([calendar isKindOfClass:[NSException class]]) {
|
||||
|
@ -224,7 +248,7 @@
|
|||
NSString *filename;
|
||||
|
||||
filename = [calendar resourceNameForEventUID:[[self inEvent] uid]];
|
||||
if (filename != nil) {
|
||||
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.
|
||||
|
@ -233,21 +257,23 @@
|
|||
|
||||
tmp = [calendar lookupName:filename inContext:[self context] acquire:NO];
|
||||
if ([tmp isNotNull] && ![tmp isKindOfClass:[NSException class]])
|
||||
self->storedEventObject = [tmp retain];
|
||||
storedEventObject = [tmp retain];
|
||||
}
|
||||
}
|
||||
|
||||
if (self->storedEventObject == nil)
|
||||
self->storedEventObject = [[NSNull null] retain];
|
||||
if (storedEventObject == nil)
|
||||
storedEventObject = [[NSNull null] retain];
|
||||
|
||||
return self->storedEventObject;
|
||||
return storedEventObject;
|
||||
}
|
||||
|
||||
- (BOOL)isEventStoredInCalendar {
|
||||
- (BOOL) isEventStoredInCalendar
|
||||
{
|
||||
return [[self storedEventObject] isNotNull];
|
||||
}
|
||||
|
||||
- (iCalEvent *)storedEvent {
|
||||
- (iCalEvent *) storedEvent
|
||||
{
|
||||
return (iCalEvent *) [(SOGoAppointmentObject *)[self storedEventObject] component: NO];
|
||||
}
|
||||
|
||||
|
@ -262,14 +288,16 @@
|
|||
return [identity objectForKey: @"email"];
|
||||
}
|
||||
|
||||
- (iCalEvent *)authorativeEvent {
|
||||
- (iCalEvent *) authorativeEvent
|
||||
{
|
||||
/* DB is considered master, when in DB, ignore mail organizer */
|
||||
return [self isEventStoredInCalendar]
|
||||
? [self storedEvent]
|
||||
: [self inEvent];
|
||||
}
|
||||
|
||||
- (BOOL)isLoggedInUserTheOrganizer {
|
||||
- (BOOL) isLoggedInUserTheOrganizer
|
||||
{
|
||||
NSString *loginEMail;
|
||||
|
||||
if ((loginEMail = [self loggedInUserEMail]) == nil) {
|
||||
|
@ -280,7 +308,8 @@
|
|||
return [[self authorativeEvent] isOrganizer:loginEMail];
|
||||
}
|
||||
|
||||
- (BOOL)isLoggedInUserAnAttendee {
|
||||
- (BOOL) isLoggedInUserAnAttendee
|
||||
{
|
||||
NSString *loginEMail;
|
||||
|
||||
if ((loginEMail = [self loggedInUserEMail]) == nil) {
|
||||
|
@ -309,7 +338,8 @@
|
|||
|
||||
/* replies */
|
||||
|
||||
- (NGImap4EnvelopeAddress *)replySenderAddress {
|
||||
- (NGImap4EnvelopeAddress *) replySenderAddress
|
||||
{
|
||||
/*
|
||||
The iMIP reply is the sender of the mail, the 'attendees' are NOT set to
|
||||
the actual attendees. BUT the attendee field contains the reply-status!
|
||||
|
@ -321,14 +351,18 @@
|
|||
return [tmp objectAtIndex:0];
|
||||
}
|
||||
|
||||
- (NSString *)replySenderEMail {
|
||||
- (NSString *) replySenderEMail
|
||||
{
|
||||
return [[self replySenderAddress] email];
|
||||
}
|
||||
- (NSString *)replySenderBaseEMail {
|
||||
|
||||
- (NSString *) replySenderBaseEMail
|
||||
{
|
||||
return [[self replySenderAddress] baseEMail];
|
||||
}
|
||||
|
||||
- (iCalPerson *)inReplyAttendee {
|
||||
- (iCalPerson *) inReplyAttendee
|
||||
{
|
||||
NSArray *attendees;
|
||||
|
||||
attendees = [[self inEvent] attendees];
|
||||
|
@ -339,7 +373,9 @@
|
|||
|
||||
return [attendees objectAtIndex:0];
|
||||
}
|
||||
- (iCalPerson *)storedReplyAttendee {
|
||||
|
||||
- (iCalPerson *) storedReplyAttendee
|
||||
{
|
||||
/*
|
||||
TODO: since an attendee can have multiple email addresses, maybe we
|
||||
should translate the email to an internal uid and then retrieve
|
||||
|
@ -350,28 +386,22 @@
|
|||
iCalEvent *e;
|
||||
iCalPerson *p;
|
||||
|
||||
if ((e = [self storedEvent]) == nil)
|
||||
return nil;
|
||||
if ((p = [e findParticipantWithEmail:[self replySenderBaseEMail]]))
|
||||
return p;
|
||||
if ((p = [e findParticipantWithEmail:[self replySenderEMail]]))
|
||||
return p;
|
||||
return nil;
|
||||
p = nil;
|
||||
|
||||
e = [self storedEvent];
|
||||
if (e)
|
||||
{
|
||||
p = [e findParticipantWithEmail: [self replySenderBaseEMail]];
|
||||
if (!p)
|
||||
p = [e findParticipantWithEmail:[self replySenderEMail]];
|
||||
}
|
||||
- (BOOL)isReplySenderAnAttendee {
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
- (BOOL) isReplySenderAnAttendee
|
||||
{
|
||||
return [[self storedReplyAttendee] isNotNull];
|
||||
}
|
||||
|
||||
/* action URLs */
|
||||
|
||||
- (id)acceptLink {
|
||||
return [[self pathToAttachmentObject] stringByAppendingString:@"/accept"];
|
||||
}
|
||||
- (id)declineLink {
|
||||
return [[self pathToAttachmentObject] stringByAppendingString:@"/decline"];
|
||||
}
|
||||
- (id)tentativeLink {
|
||||
return [[self pathToAttachmentObject] stringByAppendingString:@"/tentative"];
|
||||
}
|
||||
|
||||
@end /* UIxMailPartICalViewer */
|
||||
|
|
|
@ -25,6 +25,16 @@
|
|||
actionClass = "UIxMailPartICalAction";
|
||||
actionName = "markTentative";
|
||||
};
|
||||
addToCalendar = {
|
||||
protectedBy = "View";
|
||||
actionClass = "UIxMailPartICalAction";
|
||||
actionName = "addToCalendar";
|
||||
};
|
||||
deleteFromCalendar = {
|
||||
protectedBy = "View";
|
||||
actionClass = "UIxMailPartICalAction";
|
||||
actionName = "deleteFromCalendar";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<?xml version="1.0" standalone="yes"?>
|
||||
<!DOCTYPE div>
|
||||
<div xmlns="http://www.w3.org/1999/xhtml"
|
||||
xmlns:var="http://www.skyrix.com/od/binding"
|
||||
xmlns:label="OGo:label"
|
||||
|
@ -32,16 +33,21 @@
|
|||
</var:if>
|
||||
</legend>
|
||||
|
||||
|
||||
<!-- var:if condition="inCalendar.method" const:value="REQUEST" -->
|
||||
<var:if condition="inCalendar.method" const:value="REQUEST">
|
||||
<!-- sent to attendees to propose or update a meeting -->
|
||||
<var:if condition="isLoggedInUserAnAttendee">
|
||||
<p class="uix_ical_toolbar">
|
||||
<a var:href="acceptLink" label:string="do_accept"/> |
|
||||
<a var:href="declineLink" label:string="do_decline"/> |
|
||||
<a var:href="tentativeLink" label:string="do_tentative"/>
|
||||
<var:if condition="isEventStoredInCalendar" const:negate="1">
|
||||
| <a var:href="addToCalendarLink" label:string="do_add_to_cal" />
|
||||
<p class="uix_ical_toolbar" id="iCalendarToolbar">
|
||||
<input id="iCalendarAttachment" type="hidden"
|
||||
var:value="pathToAttachmentObject"/>
|
||||
<input id="iCalendarAccept" class="button"
|
||||
type="button" label:value="Accept"/>
|
||||
<input id="iCalendarDecline" class="button"
|
||||
type="button" label:value="Decline"/>
|
||||
<input id="iCalendarTentative" class="button"
|
||||
type="button" label:value="Tentative"/>
|
||||
<var:if condition="isEventStoredInCalendar" const:negate="YES">
|
||||
| <input id="iCalendarAddToCalendar" class="button"
|
||||
type="button" label:value="Add to calendar"/>
|
||||
</var:if>
|
||||
</p>
|
||||
|
||||
|
@ -53,7 +59,7 @@
|
|||
</p>
|
||||
</var:if>
|
||||
|
||||
<var:if condition="isLoggedInUserAnAttendee" const:negate="1">
|
||||
<var:if condition="isLoggedInUserAnAttendee" const:negate="YES">
|
||||
<p>
|
||||
<var:string label:value="Organizer" />
|
||||
<a var:href="inEvent.organizer.email"
|
||||
|
@ -61,7 +67,7 @@
|
|||
<var:string label:value="request_info_no_attendee" />
|
||||
</p>
|
||||
</var:if>
|
||||
<!-- var:if -->
|
||||
</var:if>
|
||||
|
||||
|
||||
<var:if condition="inCalendar.method" const:value="REPLY">
|
||||
|
@ -90,13 +96,13 @@
|
|||
</var:if>
|
||||
</var:if>
|
||||
|
||||
|
||||
<var:if condition="inCalendar.method" const:value="CANCEL">
|
||||
<!-- sent to attendees to notify of the attendee being removed or the
|
||||
event being deleted -->
|
||||
<var:if condition="isEventStoredInCalendar">
|
||||
<p class="uix_ical_toolbar">
|
||||
<a var:href="delFromCalendarLink" label:string="do_del_from_cal"/>
|
||||
<input id="iCalendarDeleteFromCalendar" class="button"
|
||||
type="button" label:value="Delete from calendar"/>
|
||||
</p>
|
||||
</var:if>
|
||||
|
||||
|
@ -148,7 +154,6 @@
|
|||
<br />
|
||||
</var:if>
|
||||
|
||||
|
||||
<div class="linked_attachment_meta" style="background-color: white;">
|
||||
<table border="0" class="linked_attachment_meta">
|
||||
<tr>
|
||||
|
|
|
@ -9,7 +9,7 @@ if (typeof textMailAccounts != 'undefined') {
|
|||
mailAccounts = new Array();
|
||||
}
|
||||
|
||||
var currentMessages = new Array();
|
||||
var currentMessages = {};
|
||||
var maxCachedMessages = 20;
|
||||
var cachedMessages = new Array();
|
||||
var currentMailbox = null;
|
||||
|
@ -743,13 +743,56 @@ function configureLinksInMessage() {
|
|||
if (editDraftButton)
|
||||
Event.observe(editDraftButton, "click",
|
||||
onMessageEditDraft.bindAsEventListener(editDraftButton));
|
||||
|
||||
configureiCalLinksInMessage();
|
||||
}
|
||||
|
||||
function configureiCalLinksInMessage() {
|
||||
var buttons = { "iCalendarAccept": "accept",
|
||||
"iCalendarDecline": "decline",
|
||||
"iCalendarTentative": "tentative",
|
||||
"iCalendarAddToCalendar": "addToCalendar",
|
||||
"iCalendarDeleteFromCalendar": "deleteFromCalendar" };
|
||||
|
||||
for (var key in buttons) {
|
||||
var button = $(key);
|
||||
if (button) {
|
||||
button.action = buttons[key];
|
||||
Event.observe(button, "click",
|
||||
onICalendarButtonClick.bindAsEventListener(button));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onICalendarButtonClick(event) {
|
||||
var link = $("iCalendarAttachment").value;
|
||||
if (link) {
|
||||
var urlstr = link + "/" + this.action;
|
||||
triggerAjaxRequest(urlstr, ICalendarButtonCallback,
|
||||
currentMailbox + "/"
|
||||
+ currentMessages[currentMailbox]);
|
||||
window.alert(urlstr);
|
||||
}
|
||||
}
|
||||
|
||||
function ICalendarButtonCallback(http) {
|
||||
if (http.readyState == 4)
|
||||
if (isHttpStatus204(http.status)) {
|
||||
var oldMsg = http.callbackData;
|
||||
var msg = currentMailbox + "/" + currentMessages[currentMailbox];
|
||||
if (oldMsg == msg) {
|
||||
deleteCachedMessage(oldMsg);
|
||||
loadMessage(currentMessages[currentMailbox]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function resizeMailContent() {
|
||||
var headerTable = document.getElementsByClassName('mailer_fieldtable')[0];
|
||||
var contentDiv = document.getElementsByClassName('mailer_mailcontent')[0];
|
||||
|
||||
contentDiv.setStyle({ 'top': (Element.getHeight(headerTable) + headerTable.offsetTop) + 'px' });
|
||||
contentDiv.setStyle({ 'top':
|
||||
(Element.getHeight(headerTable) + headerTable.offsetTop) + 'px' });
|
||||
}
|
||||
|
||||
function onMessageContentMenu(event) {
|
||||
|
|
Loading…
Reference in a new issue