+2004-12-09 Marcus Mueller <znek@mulle-kybernetik.com>
+
+ * v0.9.97
+
+ * UIxAppointmentEditor.[wox,m]: provided API and UI for marking an
+ event as being private or public, public being the default.
+
+ * English.lproj/default.strings: provided additional localizable
+ strings for event "classification" (private/public).
+
+ * UIxAppointmentEditor.m: set 'transparency' of new items to
+ 'TRANSPARENT' instead of 'OPAQUE'. In agenor FreeBusy information is
+ constrained by a folder flag instead of individual events, however
+ the intent is to permit retrieval of FreeBusy information in general.
+ Please note that the according information isn't properly parsed/set
+ in loadValues/saveValues as of now - the underlying iCalEvent doesn't
+ handle this as of now.
+
2004-12-08 Marcus Mueller <znek@mulle-kybernetik.com>
* v0.9.96
"Location" = "Location";
"Priority" = "Priority";
"Categories" = "Categories";
+"Classification" = "Classification";
"Duration" = "Duration";
"Participants" = "Participants";
"Resources" = "Resources";
"attributes" = "Attributes";
"participants" = "Participants";
+"is private" = "is private";
/* Searching */
NSArray *resources; /* array of iCalPerson's */
NSString *priority;
NSArray *categories;
+ NSString *accessClass;
+ BOOL isPrivate; /* default: NO */
}
- (NSString *)iCalStringTemplate;
- (NSString *)iCalString;
+- (void)setIsPrivate:(BOOL)_yn;
+- (void)setAccessClass:(NSString *)_class;
+
- (NSString *)_completeURIForMethod:(NSString *)_method;
- (iCalPerson *)getOrganizer;
@implementation UIxAppointmentEditor
+- (id)init {
+ self = [super init];
+ if(self) {
+ [self setIsPrivate:NO];
+ }
+ return self;
+}
+
- (void)dealloc {
+ [self->iCalString release];
[self->errorText release];
- [self->participants release];
- [self->resources release];
+ [self->item release];
+
[self->startDate release];
[self->endDate release];
[self->title release];
[self->location release];
[self->comment release];
+ [self->participants release];
+ [self->resources release];
[self->priority release];
[self->categories release];
- [self->iCalString release];
- [self->item release];
+ [self->accessClass release];
[super dealloc];
}
5 == normal
1 == high
*/
- return [NSArray arrayWithObjects:
- @"0", @"5", @"1", nil];
+ static NSArray *priorities = nil;
+
+ if (!priorities)
+ priorities = [[NSArray arrayWithObjects:@"0", @"5", @"1", nil] retain];
+ return priorities;
}
- (NSString *)itemPriorityText {
– holidays,
– phone.
*/
- return [NSArray arrayWithObjects:
- @"APPOINTMENT",
- @"NOT IN OFFICE",
- @"MEETING",
- @"HOLIDAY",
- @"PHONE CALL",
- nil];
+ static NSArray *categoryItems = nil;
+
+ if (!categoryItems) {
+ categoryItems = [[NSArray arrayWithObjects:@"APPOINTMENT",
+ @"NOT IN OFFICE",
+ @"MEETING",
+ @"HOLIDAY",
+ @"PHONE CALL",
+ nil] retain];
+ }
+ return categoryItems;
}
- (NSString *)itemCategoryText {
return self->categories;
}
+/* class */
+
+#if 0
+- (NSArray *)accessClassItems {
+ static NSArray classItems = nil;
+
+ if (!classItems) {
+ return [[NSArray arrayWithObjects:@"PUBLIC", @"PRIVATE", nil] retain];
+ }
+ return classItems;
+}
+#endif
+
+- (void)setAccessClass:(NSString *)_class {
+ ASSIGN(self->accessClass, _class);
+}
+- (NSString *)accessClass {
+ return self->accessClass;
+}
+
+- (void)setIsPrivate:(BOOL)_yn {
+ if (_yn)
+ [self setAccessClass:@"PRIVATE"];
+ else
+ [self setAccessClass:@"PUBLIC"];
+ self->isPrivate = _yn;
+}
+
+- (BOOL)isPrivate {
+ return self->isPrivate;
+}
+
+
+/* transparency */
+
+- (NSString *)transparency {
+ return @"TRANSPARENT";
+}
+
/* iCal */
@"VERSION:2.0\r\n"
@"BEGIN:VEVENT\r\n"
@"UID:%@\r\n"
- @"CLASS:PRIVATE\r\n"
+ @"CLASS:PUBLIC\r\n"
@"STATUS:CONFIRMED\r\n"
@"DTSTAMP:%@\r\n"
@"DTSTART:%@\r\n"
@"DTEND:%@\r\n"
- @"TRANSP:OPAQUE\r\n"
+ @"TRANSP:%@\r\n"
@"SEQUENCE:1\r\n"
@"PRIORITY:5\r\n"
@"%@"
[[NSCalendarDate date] icalString],
[lStartDate icalString],
[lEndDate icalString],
+ [self transparency],
s];
return template;
}
}
- (void)loadValuesFromAppointment:(SOGoAppointment *)_appointment {
+ NSString *s;
+
if ((self->startDate = [[_appointment startDate] copy]) == nil)
- self->startDate = [[[[NSCalendarDate date] date] hour:11 minute:0] copy];
- if ((self->endDate = [[_appointment endDate] copy]) == nil) {
+ self->startDate = [[[NSCalendarDate date] hour:11 minute:0] copy];
+ if ((self->endDate = [[_appointment endDate] copy]) == nil) {
self->endDate =
- [[self->startDate hour:[self->startDate hourOfDay]+1 minute:0] copy];
+ [[self->startDate hour:[self->startDate hourOfDay] + 1 minute:0] copy];
}
[self->startDate setTimeZone:[self viewTimeZone]];
[self->endDate setTimeZone:[self viewTimeZone]];
self->categories = [[_appointment categories] retain];
self->participants = [[_appointment participants] retain];
self->resources = [[_appointment resources] retain];
+
+ s = [_appointment accessClass];
+ if(!s || [s isEqualToString:@"PUBLIC"])
+ [self setIsPrivate:NO];
+ else
+ [self setIsPrivate:YES]; /* we're possibly loosing information here */
}
- (void)saveValuesIntoAppointment:(SOGoAppointment *)_appointment {
[_appointment setPriority:[self priority]];
[_appointment setCategories:[self categories]];
+ [_appointment setAccessClass:[self accessClass]];
+ [_appointment setTransparency:[self transparency]];
+
attendees = [self participants];
lResources = [self resources];
if ([lResources count] > 0) {
</span>
</td>
</tr>
+ <tr valign="top">
+ <td align="right" width="15%">
+ <span class="aptview_text">
+ <var:string label:value="Classification" />:
+ </span>
+ </td>
+ <td align="left" bgcolor="#FFFFF0">
+ <span class="aptview_text">
+ <input type="checkbox"
+ var:selection="isPrivate"
+ var:checked="isPrivate"
+ /> <var:string label:value="is private" />
+ </span>
+ </td>
+ </tr>
</table>
</td>
</tr>
# $Id$
-SUBMINOR_VERSION:=96
+SUBMINOR_VERSION:=97
# v0.9.96 requires SOGoLogic v0.9.27
# v0.9.94 requires NGExtensions v4.5.136
+2004-12-09 Marcus Mueller <znek@mulle-kybernetik.com>
+
+ * v0.9.28
+
+ * SOGoAppointment.[hm]: added API for accessClass ("CLASS:") and
+ transparency ("TRANSP:"). While accessClass is properly handled
+ by the underlying iCalEvent, transparency is not. SOGoAppointment
+ handles the default cases for agenor currently, so other parts
+ can rely on this information.
+
+ * SOGoAppointmentICalRenderer.m: removed static assumptions for
+ accessClass and transparency, changed to query SOGoAppointment
+ for this information.
+
2004-12-08 Marcus Mueller <znek@mulle-kybernetik.com>
* SOGoAppointment.[hm]: added checks to see whether a given email
- (void)setOrganizer:(iCalPerson *)_organizer;
- (iCalPerson *)organizer;
+- (void)setAccessClass:(NSString *)_value;
+- (NSString *)accessClass;
+
+- (void)setTransparency:(NSString *)_value;
+- (NSString *)transparency;
+
- (void)removeAllAttendees;
- (void)addToAttendees:(iCalPerson *)_person;
- (void)appendAttendees:(NSArray *)_persons;
#include "SOGoAppointmentICalRenderer.h"
#include "common.h"
+@interface iCalPerson(UIx_Privates)
+- (NSString *)rfc822Email;
+@end
+
@interface SOGoAppointment (PrivateAPI)
- (NSArray *)_filteredAttendeesThinkingOfPersons:(BOOL)_persons;
@end
@implementation SOGoAppointment
-static id<NSObject,SaxXMLReader> parser = nil;
-static SaxObjectDecoder *sax = nil;
+static id<NSObject,SaxXMLReader> parser = nil;
+static SaxObjectDecoder *sax = nil;
+static NGLogger *logger = nil;
+ (void)initialize {
- if (parser == nil) {
- parser = [[[SaxXMLReaderFactory standardXMLReaderFactory]
- createXMLReaderForMimeType:@"text/calendar"]
- retain];
- if (parser == nil)
- NSLog(@"ERROR: did not find a parser for text/calendar!");
- }
- if (sax == nil) {
- sax = [[SaxObjectDecoder alloc] initWithMappingNamed:@"NGiCal"];
- if (sax == nil)
- NSLog(@"ERROR: could not create the iCal SAX handler!");
- }
-
+ NGLoggerManager *lm;
+ SaxXMLReaderFactory *factory;
+ static BOOL didInit = NO;
+
+ if (didInit) return;
+
+ lm = [NGLoggerManager defaultLoggerManager];
+ logger = [lm loggerForClass:self];
+
+ factory = [SaxXMLReaderFactory standardXMLReaderFactory];
+ parser = [[factory createXMLReaderForMimeType:@"text/calendar"]
+ retain];
+ if (parser == nil)
+ [logger fatalWithFormat:@"did not find a parser for text/calendar!"];
+ sax = [[SaxObjectDecoder alloc] initWithMappingNamed:@"NGiCal"];
+ if (sax == nil)
+ [logger fatalWithFormat:@"could not create the iCal SAX handler!"];
+
[parser setContentHandler:sax];
[parser setErrorHandler:sax];
}
return [self->event durationAsTimeInterval];
}
+- (void)setAccessClass:(NSString *)_value {
+ [self->event setAccessClass:_value];
+}
+- (NSString *)accessClass {
+ NSString *s;
+
+ s = [self->event accessClass];
+ if(!s)
+ s = @"PUBLIC"; /* default for agenor */
+ return s;
+}
+
+- (void)setTransparency:(NSString *)_value {
+ [self debugWithFormat:@"transparency currently unsupported by iCalEvent!"];
+}
+- (NSString *)transparency {
+ [self debugWithFormat:@"returning bogus transparency information!"];
+ return @"TRANSPARENT";
+}
+
- (void)setOrganizer:(iCalPerson *)_organizer {
[self->event setOrganizer:_organizer];
}
return ms;
}
+/* logging */
+
+- (id)logger {
+ return logger;
+}
+
@end /* SOGoAppointment */
[s appendString:[_apt status]];
[s appendString:@"\r\n"];
-
- /* what's all this? */
- [s appendString:@"TRANSP:OPAQUE\r\n"]; /* transparency */
- [s appendString:@"CLASS:PRIVATE\r\n"]; /* classification [like 'top secret'] */
+ [s appendString:@"TRANSP:"];
+ [s appendString:[_apt transparency]];
+ [s appendString:@"\r\n"];
+
+ [s appendString:@"CLASS:"];
+ [s appendString:[_apt accessClass]];
+ [s appendString:@"\r\n"];
[self addOrganizer:[_apt organizer] toString:s];
[self addAttendees:[_apt attendees] toString:s];
# Version file
-SUBMINOR_VERSION:=27
+SUBMINOR_VERSION:=28
# v0.9.26 requires NGExtensions v4.5.136
# v0.9.23 requires NGiCal v4.3.32