Show plain/calendar mail parts.
*/
-@class SOGoDateFormatter;
+@class SOGoDateFormatter, SOGoAppointment;
+@class iCalEvent;
@interface UIxMailPartICalViewer : UIxMailPartViewer
{
- id appointment;
- id attendee;
+ SOGoAppointment *appointment;
+ id attendee;
SOGoDateFormatter *dateFormatter;
- id item;
+ id item;
+ id storedEventObject;
+ iCalEvent *storedEvent;
}
@end
#include <SOGoUI/SOGoDateFormatter.h>
#include <SOGo/SOGoAppointment.h>
+#include <SOGo/SOGoUser.h>
+#include <SOGo/SoObjects/Appointments/SOGoAppointmentFolder.h>
+#include <SOGo/SoObjects/Appointments/SOGoAppointmentObject.h>
+#include <NGiCal/NGiCal.h>
#include "common.h"
@implementation UIxMailPartICalViewer
- (void)dealloc {
+ [self->storedEventObject release];
+ [self->storedEvent release];
[self->attendee release];
[self->item release];
[self->appointment release];
[super dealloc];
}
-// TODO: flush caches
+/* maintain caches */
+
+- (void)resetPathCaches {
+ [super resetPathCaches];
+ [self->appointment release]; self->appointment = nil;
+ [self->storedEventObject release]; self->storedEventObject = nil;
+ [self->storedEvent release]; self->storedEvent = nil;
+
+ /* not strictly path-related, but useless without it anyway: */
+ [self->attendee release]; self->attendee = nil;
+ [self->item release]; self->item = nil;
+}
/* accessors */
/* below is copied from UIxAppointmentView, can we avoid that? */
-- (NSString *)tabSelection {
- NSString *selection;
-
- selection = [self queryParameterForKey:@"tab"];
- if (selection == nil)
- selection = @"attributes";
- return selection;
-}
-
- (void)setAttendee:(id)_attendee {
ASSIGN(self->attendee, _attendee);
}
return date;
}
-- (NSString *)resourcesAsString {
- NSArray *resources, *cns;
+/* calendar folder support */
+
+- (id)calendarFolder {
+ /* return scheduling calendar of currently logged-in user */
+ return [[[self context] activeUser] schedulingCalendarInContext:
+ [self context]];
+}
+
+- (id)storedEventObject {
+ /* lookup object in the users Calendar */
+ id calendar;
+
+ if (self->storedEventObject != nil)
+ return [self->storedEventObject isNotNull] ? self->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 appointment] uid]];
+ if (filename != nil) {
+ // 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]])
+ self->storedEventObject = [tmp retain];
+ }
+ }
+
+ if (self->storedEventObject == nil)
+ self->storedEventObject = [[NSNull null] retain];
+
+ return self->storedEventObject;
+}
+
+- (BOOL)isEventStoredInCalendar {
+ return [[self storedEventObject] isNotNull];
+}
+
+- (iCalEvent *)storedEvent {
+ return [[self storedEventObject] event];
+}
+
+/* organizer tracking */
+
+- (NSString *)loggedInUserEMail {
+ return [[[self context] activeUser] email];
+}
- resources = [[self appointment] resources];
- cns = [resources valueForKey:@"cnForDisplay"];
- return [cns componentsJoinedByString:@"<br />"];
+- (BOOL)isLoggedInUserTheOrganizer {
+ NSString *loginEMail;
+
+ if ((loginEMail = [self loggedInUserEMail]) == nil) {
+ [self warnWithFormat:@"Could not determine email of logged in user?"];
+ return NO;
+ }
+
+ if ([self isEventStoredInCalendar]) {
+ /* DB is considered master, when in DB, ignore mail organizer */
+ return [[self storedEvent] isOrganizer:loginEMail];
+ }
+
+ return [[self appointment] isOrganizer:loginEMail];
}
-- (NSString *)categoriesAsString {
- unsigned i, count;
- NSArray *cats;
- NSMutableString *s;
+- (BOOL)isLoggedInUserAnAttendee {
+ NSString *loginEMail;
+
+ if ((loginEMail = [self loggedInUserEMail]) == nil) {
+ [self warnWithFormat:@"Could not determine email of logged in user?"];
+ return NO;
+ }
- s = [[NSMutableString alloc] init];
- cats = [((SOGoAppointment *)self->appointment) categories];
- count = [cats count];
- for(i = 0; i < count; i++) {
- NSString *cat, *label;
-
- cat = [cats objectAtIndex:i];
- label = [self labelForKey:cat];
- [s appendString:label];
- if(i != (count - 1))
- [s appendString:@", "];
+ if ([self isEventStoredInCalendar]) {
+ /* DB is considered master, when in DB, ignore mail organizer */
+ return [[self storedEvent] isParticipant:loginEMail];
}
- return s;
+
+ return [[self appointment] isParticipant:loginEMail];
}
@end /* UIxMailPartICalViewer */
<div class="linked_attachment_body">
<var:string label:value="Appointment"/>:
<var:string value="appointment.summary" /><br />
+
+ Method: <var:string value="appointment.method" /><br/>
+
+ TODO: Storage:
+ <var:if condition="isEventStoredInCalendar">
+ <var:string label:value="The event is in your calendar." />
+ <!-- var:string value="storedEventObject" / -->
+
+ <!-- todo: show core info + differences -->
+ </var:if>
+ <var:if condition="isEventStoredInCalendar" const:negate="1">
+ <var:string label:value="The event is not in your calendar." />
+
+ <!-- TODO: show "add to calendar" toolbar button -->
+ </var:if>
+ <br />
+
+ TODO: Organizer:
+ <var:if condition="isLoggedInUserTheOrganizer">
+ You are the organizer!
+
+ <!--
+ Possible Status:
+ REPLY => check whether it matches, if not suggest change, show
+ comment
+ REFRESH => add button to resent iCal
+ COUNTER => show panel to decide on counter
+ -->
+ </var:if>
+ <var:if condition="isLoggedInUserTheOrganizer" const:negate="1">
+ You are not the organizer!
+
+ <var:if condition="isLoggedInUserAnAttendee">
+ (you are an attendee)
+ </var:if>
+ <var:if condition="isLoggedInUserAnAttendee" const:negate="1">
+ (you are NOT an attendee:
+ <var:string value="loggedInUserEMail"/>)
+ </var:if>
+ <!--
+ Possible Status:
+ REQUEST => ACCEPT, TENTATIVELY, DECLINE buttons with comment field
+ - only show buttons for attendees
+ PUBLISH => just the 'add to calendar' button, rewrite organizer?
+ ADD / CANCEL
+ DECLINE-COUNTER
+ -->
+ </var:if>
+ <br />
<div class="linked_attachment_meta">
<table border="0" class="linked_attachment_meta">
<var:string value="endTime" formatter="dateFormatter" />
</td>
</tr>
- <tr>
- <td><var:string label:value="Categories"/>:</td>
- <td><var:string value="categoriesAsString" /></td>
- </tr>
<tr>
<td><var:string label:value="Organizer"/>:</td>
><var:string value="appointment.organizer.rfc822Email" /></a>),
</td>
</tr>
-
+
<tr>
- <td><var:string label:value="Attendees"/>:</td>
+ <td valign="top"><var:string label:value="Attendees"/>:</td>
<td>
<var:foreach list="appointment.participants" item="attendee">
- <var:string value="attendee.cnForDisplay" />
- (<a var:href="attendee.email"
- ><var:string value="attendee.rfc822Email" /></a>),
- <var:component className="UIxCalParticipationStatusView"
- partStat="attendee.participationStatus" />
+ <a var:href="attendee.email"
+ ><var:string value="attendee.cnForDisplay" /></a>
+ (<var:string value="attendee.partStat" />)
+ <br />
</var:foreach>
</td>
</tr>
-
+
<tr>
<td><var:string label:value="Comment"/>:</td>
<td>