From 09eaae4869378cd62ac7e8fe0f6cc303692d94a9 Mon Sep 17 00:00:00 2001 From: znek Date: Sat, 14 Aug 2004 15:37:04 +0000 Subject: [PATCH] general enhancements git-svn-id: http://svn.opengroupware.org/SOGo/trunk@207 d1b88da0-ebda-0310-925b-ed51d893ca5b --- SOGo/SOGo.xcode/project.pbxproj | 11 ++ SOGo/UI/SOGoUI/ChangeLog | 5 + SOGo/UI/SOGoUI/README | 7 + SOGo/UI/SOGoUI/UIxComponent.h | 3 + SOGo/UI/SOGoUI/UIxComponent.m | 12 ++ SOGo/UI/SOGoUI/Version | 2 +- SOGo/UI/Scheduler/ChangeLog | 5 + SOGo/UI/Scheduler/UIxAppointmentEditor.m | 170 ++++++++++++--------- SOGo/UI/Scheduler/UIxAppointmentEditor.wox | 23 ++- SOGo/UI/Scheduler/UIxAppointmentView.h | 3 + SOGo/UI/Scheduler/UIxAppointmentView.m | 64 +++++--- SOGo/UI/Scheduler/UIxAppointmentView.wox | 124 +++++++++++---- SOGo/UI/Scheduler/Version | 2 +- SOGoLogic/AgenorUserManager.h | 4 +- SOGoLogic/AgenorUserManager.m | 2 +- SOGoLogic/ChangeLog | 15 +- SOGoLogic/SOGoAppointment.h | 9 +- SOGoLogic/SOGoAppointment.m | 49 +++++- SOGoLogic/Version | 2 +- 19 files changed, 371 insertions(+), 141 deletions(-) create mode 100644 SOGo/UI/SOGoUI/README diff --git a/SOGo/SOGo.xcode/project.pbxproj b/SOGo/SOGo.xcode/project.pbxproj index 312d1459..d051677a 100644 --- a/SOGo/SOGo.xcode/project.pbxproj +++ b/SOGo/SOGo.xcode/project.pbxproj @@ -368,6 +368,16 @@ refType = 4; sourceTree = ""; }; + AD071F6606CE66DF00A9EEF4 = { + fileEncoding = 4; + indentWidth = 8; + isa = PBXFileReference; + lastKnownFileType = text; + path = README; + refType = 4; + sourceTree = ""; + tabWidth = 8; + }; AD152B6F06AC159A002375D2 = { fileEncoding = 4; isa = PBXFileReference; @@ -416,6 +426,7 @@ AD6BCF12069D77E9003664CD, AD6BCF0E069D77E9003664CD, AD6BCF0F069D77E9003664CD, + AD071F6606CE66DF00A9EEF4, AD6BCF10069D77E9003664CD, AD6BCF11069D77E9003664CD, AD0712CA06C917A600A9EEF4, diff --git a/SOGo/UI/SOGoUI/ChangeLog b/SOGo/UI/SOGoUI/ChangeLog index 392ec75d..cffab75b 100644 --- a/SOGo/UI/SOGoUI/ChangeLog +++ b/SOGo/UI/SOGoUI/ChangeLog @@ -1,3 +1,8 @@ +2004-08-14 Marcus Mueller + + * UIxComponent.m: new method -isUIxDebugEnabled, triggered by new + default "SOGoUIxDebugEnabled" (v0.9.9) + 2004-08-13 Marcus Mueller * v0.9.8 diff --git a/SOGo/UI/SOGoUI/README b/SOGo/UI/SOGoUI/README new file mode 100644 index 00000000..18dafff8 --- /dev/null +++ b/SOGo/UI/SOGoUI/README @@ -0,0 +1,7 @@ +Defaults +======== + + +Name Value Synopsis +------------------------------------------------------------------------------ +SOGoUIxDebugEnabled BOOL Trigger display of debug UI. Default is NO. diff --git a/SOGo/UI/SOGoUI/UIxComponent.h b/SOGo/UI/SOGoUI/UIxComponent.h index 359c7c85..0676cd27 100644 --- a/SOGo/UI/SOGoUI/UIxComponent.h +++ b/SOGo/UI/SOGoUI/UIxComponent.h @@ -67,6 +67,9 @@ /* locale */ - (NSDictionary *)locale; +/* Debugging */ +- (BOOL)isUIxDebugEnabled; + @end #endif /* __UIxComponent_H_ */ diff --git a/SOGo/UI/SOGoUI/UIxComponent.m b/SOGo/UI/SOGoUI/UIxComponent.m index ccbcba10..e581e5a5 100644 --- a/SOGo/UI/SOGoUI/UIxComponent.m +++ b/SOGo/UI/SOGoUI/UIxComponent.m @@ -42,7 +42,13 @@ static NSMutableArray *abbrDayLabelKeys = nil; static NSMutableArray *monthLabelKeys = nil; static NSMutableArray *abbrMonthLabelKeys = nil; +static BOOL uixDebugEnabled = NO; + + (void)initialize { + NSUserDefaults *ud = [NSUserDefaults standardUserDefaults]; + + uixDebugEnabled = [ud boolForKey:@"SOGoUIxDebugEnabled"]; + if (MET == nil) { MET = [[NSTimeZone timeZoneWithAbbreviation:@"MET"] retain]; GMT = [[NSTimeZone timeZoneWithAbbreviation:@"GMT"] retain]; @@ -368,4 +374,10 @@ static NSMutableArray *abbrMonthLabelKeys = nil; return [[self context] valueForKey:@"locale"]; } +/* Debugging */ + +- (BOOL)isUIxDebugEnabled { + return uixDebugEnabled; +} + @end /* UIxComponent */ diff --git a/SOGo/UI/SOGoUI/Version b/SOGo/UI/SOGoUI/Version index 28292b54..81be7eb6 100644 --- a/SOGo/UI/SOGoUI/Version +++ b/SOGo/UI/SOGoUI/Version @@ -1,3 +1,3 @@ # $Id$ -SUBMINOR_VERSION:=8 +SUBMINOR_VERSION:=9 diff --git a/SOGo/UI/Scheduler/ChangeLog b/SOGo/UI/Scheduler/ChangeLog index 317a88bd..a90e2abf 100644 --- a/SOGo/UI/Scheduler/ChangeLog +++ b/SOGo/UI/Scheduler/ChangeLog @@ -1,3 +1,8 @@ +2004-08-14 Marcus Mueller + + * UIxAppointmentView.[h,m,wox], UIxAppointmentEditor.[h,m,wox]: + general enhancements, use new API. (v0.9.35) + 2004-08-13 Marcus Mueller * v0.9.34 diff --git a/SOGo/UI/Scheduler/UIxAppointmentEditor.m b/SOGo/UI/Scheduler/UIxAppointmentEditor.m index dce7694d..7f4e6619 100644 --- a/SOGo/UI/Scheduler/UIxAppointmentEditor.m +++ b/SOGo/UI/Scheduler/UIxAppointmentEditor.m @@ -24,8 +24,7 @@ /* TODO: CLEAN UP */ -@class NSString; -@class SOGoAppointment; +@class NSString, SOGoAppointment, iCalPerson; @interface UIxAppointmentEditor : UIxComponent { @@ -38,17 +37,24 @@ - (NSString *)iCalStringTemplate; - (NSString *)iCalString; +- (NSString *)emailForUser; +- (NSString *)cnForUser; + - (NSString *)_completeURIForMethod:(NSString *)_method; +- (iCalPerson *)getOrganizer; +- (NSArray *)getICalPersonsFromFormValues:(NSArray *)_values + treatAsResource:(BOOL)_isResource; @end +#include "common.h" #include #include #include #include -#include "iCalPerson+UIx.h" -#include "common.h" #include +#include +#include "iCalPerson+UIx.h" @interface NSDate(UsedPrivates) - (NSString *)icalString; // TODO: this is in NGiCal @@ -145,7 +151,6 @@ /* backend */ - - (SOGoAppointment *)appointment { if (self->appointment == nil) { self->appointment = [[SOGoAppointment alloc] @@ -154,21 +159,6 @@ return self->appointment; } -- (BOOL)hasParticipants { - return [[self participants] count] != 0; -} - -- (NSArray *)participants { -#warning TODO: FILTER ROLE! - return [self->appointment attendees]; -} - -- (NSArray *)resources { -#warning TODO: FILTER ROLE! - return [self->appointment attendees]; -} - - /* JavaScript */ - (NSString *)jsCode { @@ -231,23 +221,27 @@ return [self completeHrefForMethod:uri]; } -/* HACK: this is for agenor only */ + +/* email, cn */ + - (NSString *)emailForUser { NSString *uid; - NSRange r; -#warning !! USE USER MANAGER INSTEAD! uid = [[self user] login]; - r = [uid rangeOfString:@"@"]; - if(r.length > 0) - return uid; - return [NSString stringWithFormat:@"%@@equipement.gouv.fr", uid]; + return [[AgenorUserManager sharedUserManager] getEmailForUID:uid]; +} + +- (NSString *)cnForUser { + NSString *uid; + + uid = [[self user] login]; + return [[AgenorUserManager sharedUserManager] getCNForUID:uid]; } - (NSString *)combinedCNAndEmailForUser { return [NSString stringWithFormat:@"%@;%@", [self emailForUser], - [self shortUserNameForDisplay]]; + [self cnForUser]]; } - (NSString *)combinedCNAndEmail { @@ -289,6 +283,73 @@ return date; } +- (iCalPerson *)getOrganizer { + iCalPerson *p; + NSString *emailProp; + + emailProp = [NSString stringWithFormat:@"mailto:%@", + [self emailForUser]]; + p = [[iCalPerson alloc] init]; + [p setEmail:emailProp]; + [p setCn:[self cnForUser]]; + return [p autorelease]; +} + +- (NSArray *)getICalPersonsFromFormValues:(NSArray *)_values + treatAsResource:(BOOL)_isResource +{ + unsigned i, count; + NSMutableArray *result; + + count = [_values count]; + result = [[NSMutableArray alloc] initWithCapacity:count]; + for (i = 0; i < count; i++) { + NSString *pString, *email, *cn; + NSRange r; + iCalPerson *p; + + pString = [_values objectAtIndex:i]; + if([pString length] == 0) + continue; + + /* delimiter between email and cn */ + r = [pString rangeOfString:@";"]; + if(r.length > 0) { + email = [pString substringToIndex:r.location]; + if(r.location + 1 < [pString length]) { + cn = [pString substringFromIndex:r.location + 1]; + } + else { + cn = nil; + } + } + else { + email = pString; + cn = nil; + } + if(cn == nil) { + /* fallback */ + AgenorUserManager *um = [AgenorUserManager sharedUserManager]; + cn = [um getCNForUID:[um getUIDForEmail:email]]; + } + p = [[iCalPerson alloc] init]; + [p setEmail:[@"mailto:" stringByAppendingString:email]]; + if(cn) + [p setCn:cn]; + + /* see RFC2445, sect. 4.2.16 for details */ + if(_isResource) { + [p setRole:@"X-OGo-RESOURCE"]; + } + else { + [p setRole:@"REQ-PARTICIPANT"]; + } + [result addObject:p]; + [p release]; + } + return [result autorelease]; +} + /* for testing only */ - (id)testAction { WORequest *req; @@ -306,8 +367,7 @@ NSString *iCalString; NSString *summary, *location, *uri; NSCalendarDate *sd, *ed; - NSArray *ps; - unsigned i, count; + NSArray *attendees; WORequest *req; @@ -344,46 +404,16 @@ [apt setLocation:location]; [apt removeAllAttendees]; /* clean up */ - ps = [req formValuesForKey:@"participants"]; - count = [ps count]; - for (i = 0; i < count; i++) { - NSString *pString, *email, *cn; - NSRange r; - iCalPerson *p; - - pString = [ps objectAtIndex:i]; - if([pString length] == 0) - continue; - - /* delimiter between email and cn */ - r = [pString rangeOfString:@";"]; - if(r.length > 0) { - email = [pString substringToIndex:r.location]; - if(r.location + 1 < [pString length]) { - cn = [pString substringFromIndex:r.location + 1]; - } - else { - cn = nil; - } - } - else { - email = pString; - cn = nil; - } - if(cn == nil) { - /* construct a fake CN if possible */ - r = [email rangeOfString:@"@"]; - if (r.length > 0) - cn = [email substringToIndex:r.location]; - } - p = [[iCalPerson alloc] init]; - [p setEmail:[@"mailto:" stringByAppendingString:email]]; - if(cn) - [p setCn:cn]; - [apt addToAttendees:p]; - [p release]; - } - + attendees = \ + [self getICalPersonsFromFormValues:[req formValuesForKey:@"participants"] + treatAsResource:NO]; + [apt appendAttendees:attendees]; + attendees = \ + [self getICalPersonsFromFormValues:[req formValuesForKey:@"resources"] + treatAsResource:YES]; + [apt appendAttendees:attendees]; + [apt setOrganizer:[self getOrganizer]]; + /* receive current representation for save operation */ iCalString = [apt iCalString]; [apt release]; apt = nil; diff --git a/SOGo/UI/Scheduler/UIxAppointmentEditor.wox b/SOGo/UI/Scheduler/UIxAppointmentEditor.wox index e054b63c..3ac73b49 100644 --- a/SOGo/UI/Scheduler/UIxAppointmentEditor.wox +++ b/SOGo/UI/Scheduler/UIxAppointmentEditor.wox @@ -137,7 +137,9 @@ />
- + - + - - + + diff --git a/SOGo/UI/Scheduler/Version b/SOGo/UI/Scheduler/Version index 8c14e0bf..cd172534 100644 --- a/SOGo/UI/Scheduler/Version +++ b/SOGo/UI/Scheduler/Version @@ -1,6 +1,6 @@ # $Id$ -SUBMINOR_VERSION:=33 +SUBMINOR_VERSION:=35 # v0.9.31 requires libWEExtensions v4.2.52 # v0.9.29 requires libWEExtensions v4.2.51 diff --git a/SOGoLogic/AgenorUserManager.h b/SOGoLogic/AgenorUserManager.h index 6dff70ec..2d9177e2 100644 --- a/SOGoLogic/AgenorUserManager.h +++ b/SOGoLogic/AgenorUserManager.h @@ -35,9 +35,11 @@ + (id)sharedUserManager; -- (NSString *)getUIDForEMail:(NSString *)_email; +- (NSString *)getUIDForEmail:(NSString *)_email; - (NSString *)getEmailForUID:(NSString *)_uid; +- (NSString *)getCNForUID:(NSString *)_uid; + @end #endif /* __AgenorUserManager_H_ */ diff --git a/SOGoLogic/AgenorUserManager.m b/SOGoLogic/AgenorUserManager.m index aec2deb4..240bf544 100644 --- a/SOGoLogic/AgenorUserManager.m +++ b/SOGoLogic/AgenorUserManager.m @@ -46,7 +46,7 @@ } -- (NSString *)getUIDForEMail:(NSString *)_email { +- (NSString *)getUIDForEmail:(NSString *)_email { NSRange r; NSString *domain; diff --git a/SOGoLogic/ChangeLog b/SOGoLogic/ChangeLog index d92abf7f..f332091b 100644 --- a/SOGoLogic/ChangeLog +++ b/SOGoLogic/ChangeLog @@ -1,3 +1,16 @@ +2004-08-14 Marcus Mueller + + * v0.9.4 + + * AgenorUserManager.[hm]: fixed typo, exposed new method + -getCNForUID:. This is very naive and should be fixed to use + LDAP instead. + + * SOGoAppointment.[hm]: ROLE is set properly now. Added + -participants and -resources to differentiate between specific + roles in a UI convenient way. Resources are indentified via a + custom ROLE dubbed "X-OGo-RESOURCE". + 2004-08-13 Marcus Mueller * AgenorUserManager.[hm]: new singleton object to manage Agenor @@ -19,4 +32,4 @@ 2004-06-25 Marcus Mueller - * created. \ No newline at end of file + * created. diff --git a/SOGoLogic/SOGoAppointment.h b/SOGoLogic/SOGoAppointment.h index 1b17ed4c..1f72436a 100644 --- a/SOGoLogic/SOGoAppointment.h +++ b/SOGoLogic/SOGoAppointment.h @@ -34,6 +34,7 @@ { id calendar; id event; + id participants; } - (id)initWithICalString:(NSString *)_iCal; @@ -67,14 +68,18 @@ - (void)removeAllAttendees; - (void)addToAttendees:(iCalPerson *)_person; +- (void)appendAttendees:(NSArray *)_persons; - (NSArray *)attendees; -/* generating iCal */ +/* attendees -> role != X-OGo-RESOURCE */ +- (NSArray *)participants; +/* attendees -> role == X-OGo-RESOURCE */ +- (NSArray *)resources; +/* TODO: should have coder instead */ - (NSString *)iCalString; /* do we really need these? */ - - (id)calendar; - (id)event; diff --git a/SOGoLogic/SOGoAppointment.m b/SOGoLogic/SOGoAppointment.m index da48bd4b..419aa0bb 100644 --- a/SOGoLogic/SOGoAppointment.m +++ b/SOGoLogic/SOGoAppointment.m @@ -24,12 +24,17 @@ #include "SOGoAppointment.h" #include #include +#include #include "common.h" @interface NSDate(UsedPrivates) - (NSString *)icalString; // declared in NGiCal @end +@interface SOGoAppointment (PrivateAPI) +- (NSArray *)_filteredAttendeesThinkingOfPersons:(BOOL)_persons; +@end + @implementation SOGoAppointment static id parser = nil; @@ -185,7 +190,13 @@ static SaxObjectDecoder *sax = nil; NSString *x; p = [persons objectAtIndex:i]; - [s appendString:@"\nATTENDEE;CN=\""]; + [s appendString:@"\nATTENDEE;"]; + if((x = [p role])) { + [s appendString:@"ROLE="]; + [s appendString:x]; + [s appendString:@";"]; + } + [s appendString:@"CN=\""]; if((x = [p cn])) { [s appendString:x]; } @@ -276,8 +287,44 @@ static SaxObjectDecoder *sax = nil; - (void)addToAttendees:(iCalPerson *)_person { [self->event addToAttendees:_person]; } +- (void)appendAttendees:(NSArray *)_persons { + unsigned i, count; + + count = [_persons count]; + for(i = 0; i < count; i++) { + [self addToAttendees:[_persons objectAtIndex:i]]; + } +} - (NSArray *)attendees { return [self->event attendees]; } +- (BOOL)hasParticipants { + return [[self participants] count] != 0; +} + +- (NSArray *)participants { + if(self->participants == nil) { + ASSIGN(self->participants, + [self _filteredAttendeesThinkingOfPersons:YES]); + } + return self->participants; +} + +- (NSArray *)resources { + return [self _filteredAttendeesThinkingOfPersons:NO]; +} + +- (NSArray *)_filteredAttendeesThinkingOfPersons:(BOOL)_persons { + EOQualifier *q; + NSString *qs; + + if(_persons) + qs = @"role != X-OGo-RESOURCE"; + else + qs = @"role = X-OGo-RESOURCE"; + q = [EOQualifier qualifierWithQualifierFormat:qs]; + return [[self attendees] filteredArrayUsingQualifier:q]; +} + @end diff --git a/SOGoLogic/Version b/SOGoLogic/Version index fc795f55..749d66dc 100644 --- a/SOGoLogic/Version +++ b/SOGoLogic/Version @@ -1,3 +1,3 @@ # $Id$ -SUBMINOR_VERSION:=3 +SUBMINOR_VERSION:=4 -- 2.39.2

- +
- -
- clientObject: + +
+ clientObject: +
diff --git a/SOGo/UI/Scheduler/UIxAppointmentView.h b/SOGo/UI/Scheduler/UIxAppointmentView.h index 02f1b0c3..c068b5b7 100644 --- a/SOGo/UI/Scheduler/UIxAppointmentView.h +++ b/SOGo/UI/Scheduler/UIxAppointmentView.h @@ -5,11 +5,14 @@ #include +@class SOGoDateFormatter; + @interface UIxAppointmentView : UIxComponent { NSString *tabSelection; id appointment; id attendee; + SOGoDateFormatter *dateFormatter; } - (id)appointment; diff --git a/SOGo/UI/Scheduler/UIxAppointmentView.m b/SOGo/UI/Scheduler/UIxAppointmentView.m index 68f41da4..e04dd866 100644 --- a/SOGo/UI/Scheduler/UIxAppointmentView.m +++ b/SOGo/UI/Scheduler/UIxAppointmentView.m @@ -1,15 +1,17 @@ // $Id$ #include "UIxAppointmentView.h" -#include "common.h" #include #include +#include +#include "common.h" @implementation UIxAppointmentView - (void)dealloc { [self->appointment release]; [self->attendee release]; + [self->dateFormatter release]; [super dealloc]; } @@ -31,39 +33,57 @@ return self->attendee; } -/* backend */ - -- (SOGoAppointment *)appointment { - NSString *iCalString; - - if (self->appointment) - return self->appointment; - - iCalString = [[self clientObject] valueForKey:@"iCalString"]; - if (![iCalString isNotNull] || [iCalString length] == 0) { - [self debugWithFormat:@"ERROR(%s): missing iCal string!", - __PRETTY_FUNCTION__]; - return nil; - } - - self->appointment = [[SOGoAppointment alloc] initWithICalString:iCalString]; - return self->appointment; +- (SOGoDateFormatter *)dateFormatter { + if(self->dateFormatter == nil) { + self->dateFormatter = \ + [[SOGoDateFormatter alloc] initWithLocale:[self locale]]; + [self->dateFormatter setFullWeekdayNameAndDetails]; + } + return self->dateFormatter; } -- (NSString *)formattedAptStartTime { +- (NSCalendarDate *)startTime { NSCalendarDate *date; date = [[self appointment] startDate]; [date setTimeZone:[self viewTimeZone]]; - return [date descriptionWithCalendarFormat:@"%A, %Y-%m-%d %H:%M %Z"]; + return date; } -- (NSString *)formattedAptEndTime { +- (NSCalendarDate *)endTime { NSCalendarDate *date; date = [[self appointment] endDate]; [date setTimeZone:[self viewTimeZone]]; - return [date descriptionWithCalendarFormat:@"%A, %Y-%m-%d %H:%M %Z"]; + return date; +} + +- (NSString *)resourcesAsString { + NSArray *resources, *cns; + + resources = [[self appointment] resources]; + cns = [resources valueForKey:@"cnForDisplay"]; + return [cns componentsJoinedByString:@"
"]; +} + + +/* backend */ + +- (SOGoAppointment *)appointment { + NSString *iCalString; + + if (self->appointment) + return self->appointment; + + iCalString = [[self clientObject] valueForKey:@"iCalString"]; + if (![iCalString isNotNull] || [iCalString length] == 0) { + [self debugWithFormat:@"ERROR(%s): missing iCal string!", + __PRETTY_FUNCTION__]; + return nil; + } + + self->appointment = [[SOGoAppointment alloc] initWithICalString:iCalString]; + return self->appointment; } diff --git a/SOGo/UI/Scheduler/UIxAppointmentView.wox b/SOGo/UI/Scheduler/UIxAppointmentView.wox index b7a226db..9b7138cf 100644 --- a/SOGo/UI/Scheduler/UIxAppointmentView.wox +++ b/SOGo/UI/Scheduler/UIxAppointmentView.wox @@ -27,25 +27,40 @@ - +
- + - - - + + + + + + + + + + + +
+ printview + edit + - + var:href="attributesTabLink" + > +
@@ -112,11 +130,45 @@ -
Start time: - +
- +
+
+ Resources: + + + + +
+ Organizer: + + + + +
+ Comment: + + + + +
Email
@@ -140,34 +194,40 @@ + >
- - SOGo Server - -
- Client: -
- Group:
- Deletable:
- Generation:
- MsgClass:
- -
- As iCal:
-
- -
- As Mail:
-
- -
+ + + SOGo Server - +
+ Client: +
+ Group:
+ Deletable:
+ Generation:
+ MsgClass:
+ +
+ As iCal:
+
+ +
+ As Mail:
+
+ +
+