]> err.no Git - scalable-opengroupware.org/commitdiff
git-svn-id: http://svn.opengroupware.org/SOGo/trunk@233 d1b88da0-ebda-0310-925b-ed51d...
authorhelge <helge@d1b88da0-ebda-0310-925b-ed51d893ca5b>
Sun, 15 Aug 2004 19:09:40 +0000 (19:09 +0000)
committerhelge <helge@d1b88da0-ebda-0310-925b-ed51d893ca5b>
Sun, 15 Aug 2004 19:09:40 +0000 (19:09 +0000)
SOGo/UI/Anais/AnaisAttendeeSelector.m
SOGo/UI/Anais/ChangeLog
SOGo/UI/Anais/Version
SOGo/UI/Scheduler/ChangeLog
SOGo/UI/Scheduler/UIxAppointmentEditor.m
SOGo/UI/Scheduler/UIxAppointmentEditor.wox
SOGo/UI/Scheduler/Version
SOGo/UI/Scheduler/iCalPerson+UIx.m
SOGo/UI/Scheduler/product.plist

index cfcc02c9c827a786e30443053426773aec1312d7..4eba737dfce6b7dbbd30333f8c4af2a2add7d1a9 100644 (file)
@@ -34,6 +34,7 @@
     division     - Anais division
     emailForUser - default EMail
     cnForUser    - default CN
+    role         - role for submitted attendees
 
   Sample:
     <var:component className="AnaisAttendeeSelector"
@@ -53,6 +54,7 @@
   iCalPerson *attendee;
   NSString   *emailForUser;
   NSString   *cnForUser;
+  NSString   *role;
   struct {
     int withCN:1;
     int reserved:31;
 @end
 
 #include <NGiCal/NGiCal.h>
+#include <SOGoLogic/AgenorUserManager.h>
 #include <Scheduler/iCalPerson+UIx.h>
 #include <NGObjWeb/WOContext.h>
+#include <NGObjWeb/WORequest.h>
 #include "common.h"
 
 @implementation AnaisAttendeeSelector
 
 - (void)dealloc {
+  [self->role         release];
   [self->emailForUser release];
   [self->cnForUser    release];
   [self->division     release];
   return self->division;
 }
 
+- (void)setRole:(NSString *)_value {
+  ASSIGNCOPY(self->role, _value);
+}
+- (NSString *)role {
+  return self->role;
+}
+
 - (void)setEmailForUser:(NSString *)_value {
   ASSIGNCOPY(self->emailForUser, _value);
 }
 
 /* handling requests */
 
+- (NSArray *)getICalPersonsFromFormValues:(NSArray *)_values {
+  unsigned i, count;
+  NSMutableArray *result;
+
+  count = [_values count];
+  result = [NSMutableArray arrayWithCapacity: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) {
+      /* sample: 'test.et.di.cete-lyon@equipement.gouv.fr;test' */
+      email = [pString substringToIndex:r.location];
+      cn    = [pString substringFromIndex:r.location + r.length];
+      if ([cn length] == 0) 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 isNotNull]) [p setCn:cn];
+    
+    /* see RFC2445, sect. 4.2.16 for details */
+    [p setRole:[self role]];
+    [result addObject:p];
+    [p release];
+  }
+  return result;
+}
 - (void)takeValuesFromRequest:(WORequest *)_rq inContext:(WOContext *)_ctx {
-  [self logWithFormat:@"Note: will take values ..."];
-  [super takeValuesFromRequest:_rq inContext:_ctx];
+  /* OK, we have a special form value processor */
+  NSArray *tmp;
+  
+  [self debugWithFormat:@"Note: will take values ..."];
+  
+  tmp = [self getICalPersonsFromFormValues:
+               [_rq formValuesForKey:[self checkboxId]]];
+  [self debugWithFormat:@"  got %i attendees: %@", [tmp count], tmp];
+  [self setAttendees:tmp];
 }
 
 /* response generation */
index 37b725780a51ad01f2e3083480385f0add841a43..c04f8f8680d4eb7dacf8d546436d3c25ace214c9 100644 (file)
@@ -1,5 +1,7 @@
 2004-08-15  Helge Hess  <helge.hess@skyrix.com>
 
+       * AnaisAttendeeSelector.m: added form processing code (v0.9.7)
+
        * AnaisAttendeeSelector.m: added support for default attendees (as used
          by the editor component) (v0.9.6)
 
index eefed92535a14602fc6fbfa950c1a6573a1c6d78..29a2806a15987fcf9d3c07ee32fc016e465bec4b 100644 (file)
@@ -1,3 +1,3 @@
 # $Id: Version 165 2004-08-05 17:55:50Z znek $
 
-SUBMINOR_VERSION:=5
+SUBMINOR_VERSION:=7
index b9f02c9acfc73dc2a4e518b327f6cd82d06c3fc2..732da32a7d1ab3ac2c4e3ce0faa14a80b0d932e5 100644 (file)
@@ -1,5 +1,14 @@
 2004-08-15  Helge Hess  <helge.hess@skyrix.com>
 
+       * v0.9.46
+       
+       * iCalPerson+UIx.m: changed -cnForDisplay method, znek needs to check
+         it for correctness
+
+       * UIxAppointmentEditor.m: rewrote not to work directly on the parsed
+         iCalendar appointment but rather track changes in the appointment
+         itself
+       
        * UIxAppointmentEditor.m: removed now unused methods (due to attendee
          selector) (v0.9.45)
 
@@ -13,7 +22,7 @@
 2004-08-15  Marcus Mueller  <znek@mulle-kybernetik.com>
 
        * v0.9.43
-
+       
        * UIxTimeSelector.[wox,m]: new component for selecting the time part
          of a given date.
 
index 767ec69a8d3a60a56ffa3a393393d33b61ae6f20..8922837fde7b3bdd1010ccd30f531ffc98859570 100644 (file)
 
 @interface UIxAppointmentEditor : UIxComponent
 {
+  NSString *iCalString;
   id appointment;
-  id participants;
   id item;
+  
+  /* individual values */
+  NSCalendarDate *startDate;
+  NSCalendarDate *endDate;
+  NSString       *title;
+  NSString       *location;
+  NSString       *comment;
+  NSArray        *participants;
+  NSArray        *resources;
 }
 
 - (SOGoAppointment *)appointment;
 - (NSString *)icalString; // TODO: this is in NGiCal
 @end
 
-@interface NSObject(AppointmentHack)
-- (BOOL)isAppointment;
-@end
-
-@implementation NSObject(AppointmentHack)
-- (BOOL)isAppointment {
-  return [self isKindOfClass:NSClassFromString(@"SOGoAppointmentObject")];
-}
-@end
-
 @implementation UIxAppointmentEditor
 
 - (void)dealloc {
-  [self->appointment  release];
   [self->participants release];
+  [self->resources    release];
+  [self->startDate    release];
+  [self->endDate      release];
+  [self->title        release];
+  [self->location     release];
+  [self->comment      release];
+  [self->iCalString   release];
+  [self->appointment  release];
   [self->item         release];
   [super dealloc];
 }
   return fmt;
 }
 
+- (void)setAptStartDate:(NSCalendarDate *)_date {
+  ASSIGN(self->startDate, _date);
+}
 - (NSCalendarDate *)aptStartDate {
-  NSCalendarDate *date;
-    
-  date = [[[[self appointment] startDate] copy] autorelease];
-  [date setTimeZone:[self viewTimeZone]];
-  return date;
+  return self->startDate;
+}
+- (void)setAptEndDate:(NSCalendarDate *)_date {
+  ASSIGN(self->endDate, _date);
 }
-
 - (NSCalendarDate *)aptEndDate {
-  NSCalendarDate *date;
-    
-  date = [[[[self appointment] endDate] copy] autorelease];
-  [date setTimeZone:[self viewTimeZone]];
-  return date;
+  return self->endDate;
+}
+
+- (void)setTitle:(NSString *)_value {
+  ASSIGNCOPY(self->title, _value);
+}
+- (NSString *)title {
+  return self->title;
+}
+- (void)setLocation:(NSString *)_value {
+  ASSIGNCOPY(self->location, _value);
+}
+- (NSString *)location {
+  return self->location;
+}
+- (void)setComment:(NSString *)_value {
+  ASSIGNCOPY(self->comment, _value);
+}
+- (NSString *)comment {
+  return self->comment;
 }
 
-- (BOOL)isNewAppointment {
-  /* that doesn't work! (TODO: explain why!) */
-  // TODO: is this actually used?
-  return ![[self clientObject] isAppointment];
+- (void)setParticipants:(NSArray *)_parts {
+  ASSIGN(self->participants, _parts);
+}
+- (NSArray *)participants {
+  return self->participants;
+}
+- (void)setResources:(NSArray *)_res {
+  ASSIGN(self->resources, _res);
+}
+- (NSArray *)resources {
+  return self->resources;
 }
 
+/* iCal */
+
+- (void)setICalString:(NSString *)_s {
+  ASSIGNCOPY(self->iCalString, _s);
+}
 - (NSString *)iCalString {
-  // TODO: improve check for new appointment
-  NSString *ical;
-  
-  ical = [[self clientObject] valueForKey:@"iCalString"];
-  if ([ical length] == 0) /* a new appointment */
-    ical = [self iCalStringTemplate];
-  
-  return ical;
+  return self->iCalString;
 }
 
 - (NSString *)iCalStringTemplate {
     @"SEQUENCE:1\n"
     @"END:VEVENT\n"
     @"END:VCALENDAR";
-  NSCalendarDate *startDate, *endDate;
+  NSCalendarDate *lStartDate, *lEndDate;
   NSString       *template;
   
-  startDate = [self selectedDate];
-  endDate   = [startDate dateByAddingYears:0 months:0 days:0
+  lStartDate = [self selectedDate];
+  lEndDate   = [lStartDate dateByAddingYears:0 months:0 days:0
                          hours:1 minutes:0 seconds:0];
   
   template = [NSString stringWithFormat:iCalStringTemplate,
                         [[self clientObject] nameInContainer],
                         [[NSCalendarDate date] icalString],
-                        [startDate icalString],
-                        [endDate   icalString]];
+                        [lStartDate icalString],
+                        [lEndDate   icalString]];
   return template;
 }
 
-
-/* backend */
-
 - (SOGoAppointment *)appointment {
-  if (self->appointment == nil) {
-    self->appointment = [[SOGoAppointment alloc]
-                         initWithICalString:[self iCalString]];
-  }
   return self->appointment;
 }
 
   return [result autorelease];
 }
 
+- (BOOL)isWriteableClientObject {
+  return [[self clientObject] 
+               respondsToSelector:@selector(saveContentString:)];
+}
+
+- (void)loadValuesFromAppointment:(SOGoAppointment *)_appointment {
+  self->startDate = [[_appointment startDate] copy];
+  self->endDate   = [[_appointment endDate]   copy];
+  [self->startDate setTimeZone:[self viewTimeZone]];
+  [self->endDate   setTimeZone:[self viewTimeZone]];
+  
+  self->title    = [[_appointment summary]  copy];
+  self->location = [[_appointment location] copy];
+  self->comment  = [[_appointment comment]  copy];
+  
+  self->participants = [[_appointment participants] retain];
+  self->resources    = [[_appointment resources]    retain];
+}
+
 /* actions */
 
+- (BOOL)shouldTakeValuesFromRequest:(WORequest *)_rq inContext:(WOContext*)_c{
+  return YES;
+}
+
 - (id)testAction {
   /* for testing only */
   WORequest *req;
   return self;
 }
 
+- (id)defaultAction {
+  NSString *ical;
+  
+  /* load iCalendar file */
+  
+  ical = [[self clientObject] valueForKey:@"iCalString"];
+  if ([ical length] == 0) /* a new appointment */
+    ical = [self iCalStringTemplate];
+  
+  [self setICalString:ical];
+  
+  /* parse */
+  
+  self->appointment = 
+    [[SOGoAppointment alloc] initWithICalString:[self iCalString]];
+  
+  /* load values */
+  
+  [self loadValuesFromAppointment:[self appointment]];
+  
+  return self;
+}
+
 - (id)saveAction {
-  SOGoAppointment *apt;
-  NSString       *iCalString;
   NSString       *uri;
   NSCalendarDate *sd, *ed;
-  NSArray        *attendees, *resources;
+  NSArray        *attendees, *lResources;
   WORequest      *req;
   
-  if (![[self clientObject] respondsToSelector:@selector(saveContentString:)]){
+  if (![self isWriteableClientObject]) {
     /* return 400 == Bad Request */
     return [NSException exceptionWithHTTPStatus:400
                         reason:@"method cannot be invoked on "
   }
   
   req = [[self context] request];
-
+  
   /* get iCalString from hidden input */
-  iCalString = [req formValueForKey:@"ical"];
-  if ([iCalString length] == 0) {
-    // TODO: improve user experience ... (eg error panel like Zope)
-    /* return 400 == Bad Request */
-    return [NSException exceptionWithHTTPStatus:400 /* Bad Request */
-                        reason:@"missing iCalendar form data in request"];
-  }
+  [self setICalString:[req formValueForKey:@"ical"]];
+
+  self->appointment = 
+    [[SOGoAppointment alloc] initWithICalString:[self iCalString]];
   
-  apt = [[SOGoAppointment alloc] initWithICalString:iCalString];
-  if (apt == nil) {
+  if (self->appointment == nil) {
     return [NSException exceptionWithHTTPStatus:400 /* Bad Request */
                         reason:@"invalid iCalendar form data in request"];
   }
   
   sd = [self _dateFromString:[req formValueForKey:@"startDate"]];
   ed = [self _dateFromString:[req formValueForKey:@"endDate"]];
-  [apt setStartDate:sd];
-  [apt setEndDate:ed];
+  [self->appointment setStartDate:sd];
+  [self->appointment setEndDate:ed];
   
-  [apt setSummary:[req formValueForKey:@"summary"]];
-  [apt setLocation:[req formValueForKey:@"location"]];
+  [self->appointment setSummary:[req formValueForKey:@"summary"]];
+  [self->appointment setLocation:[req formValueForKey:@"location"]];
   
   attendees = [self getICalPersonsFromFormValues:
                      [req formValuesForKey:@"participants"]
                    treatAsResource:NO];
-  resources = [self getICalPersonsFromFormValues:
+  lResources = [self getICalPersonsFromFormValues:
                      [req formValuesForKey:@"resources"]
                    treatAsResource:YES];
-  if ([resources count] > 0) {
+  if ([lResources count] > 0) {
     attendees = ([attendees count] > 0)
-      ? [attendees arrayByAddingObjectsFromArray:resources]
-      : resources;
+      ? [attendees arrayByAddingObjectsFromArray:lResources]
+      : lResources;
   }
-  [apt setAttendees:attendees];
+  [self->appointment setAttendees:attendees];
   
-  [apt setOrganizer:[self getOrganizer]];
+  [self->appointment setOrganizer:[self getOrganizer]];
   
   /* receive current representation for save operation */
-  iCalString = [apt iCalString];
-  [apt release]; apt = nil;
-  
   {
     NSException *ex;
+    NSString *content;
+    
+    content = [self->appointment iCalString];
+    if (content == nil) {
+      return [NSException exceptionWithHTTPStatus:500 /* Internal Error */
+                         reason:@"failed to create iCal content for apt"];
+    }
     
-    ex = [[self clientObject] saveContentString:iCalString];
+    ex = [[self clientObject] saveContentString:content];
     if (ex) return ex;
     // TODO: add some error handling in form! (eg like in Zope)
   }
index ed544bac91bfa1255506d855196cc76d4248f06d..d32b0c0e17ffabb27c54ee387cf0b9b8a5e152e4 100644 (file)
@@ -86,7 +86,7 @@
               <td align="left" bgcolor="#FFFFF0">
                 <span class="aptview_text">
                   <input type="text" name="summary" const:size="40"
-                         var:value="appointment.summary" />
+                         var:value="title" />
                 </span>
               </td>
             </tr>
@@ -99,7 +99,7 @@
               <td align="left" bgcolor="#FFFFF0">
                 <span class="aptview_text">
                   <input type="text" name="location" const:size="40"
-                         var:value="appointment.location" />
+                         var:value="location" />
                 </span>
               </td>
             </tr>
                     const:selectorID="participant"
                     const:division="CC"
                     const:withCN="YES"
-                    attendees="appointment.participants"
+                    const:role="REQ-PARTICIPANT"
+                    attendees="participants"
                     var:emailForUser="emailForUser"
                     var:cnForUser="cnForUser"
                   />
                 <span class="aptview_text">
                   <var:component className="AnaisAttendeeSelector"
                     const:selectorID="resource"
-                    attendees="appointment.resources"
+                    const:role="NON-PARTICIPANT"
+                    attendees="resources"
                     const:division="CC"
                   />
                 </span>
               <td align="left" bgcolor="#FFFFF0">
                 <span class="aptview_text">
                   <textarea name="comment" rows="8" cols="80" wrap="physical"
-                            var:value="appointment.comment" />
+                            var:value="comment" />
                 </span>
               </td>
             </tr>
index 49e5e3e5590e22804263b080ad53e0612b141a77..3c9ce3a1b05de8e9f50286711fc3f9b1415fda6e 100644 (file)
@@ -1,6 +1,6 @@
 # $Id$
 
-SUBMINOR_VERSION:=45
+SUBMINOR_VERSION:=46
 
 # v0.9.41 requires libNGObjWeb     v4.2.431
 # v0.9.31 requires libWEExtensions v4.2.52
index 14ab19eb06a1e922a3ad525f121225cca0f3e990..b2581df73f7e160e8be3ad3e5a6fcc8b70fa1001 100644 (file)
 }
 
 - (NSString *)cnForDisplay {
-    NSString *_cn;
-    _cn = [self cn];
-    if([_cn length] > 2)
-        return [_cn substringWithRange:NSMakeRange(1, [_cn length] - 2)];
-    return _cn;
+#if 1
+#  warning TODO: ask znek what this was good for
+  return [self cn];
+#else
+  NSString *_cn;
+  
+  /* Note: this breaks the CN with the new appointment editor */
+  /* if this is for quoting, we need to actually check for quotes! */
+  _cn = [self cn];
+  if ([_cn length] > 2)
+    return [_cn substringWithRange:NSMakeRange(1, [_cn length] - 2)];
+  return _cn;
+#endif
 }
 
 @end /* iCalPerson(Convenience) */
index 0810af842a727ad178a7079f1cfc1bee7142f0c9..aeff30c5a3b872f5dd20e24ab0d4c01e5c7430d2 100644 (file)
           pageName    = "UIxAppointmentEditor"; 
           actionName  = "save";
         };
+        test = { 
+          protectedBy = "View";
+          pageName    = "UIxAppointmentEditor"; 
+          actionName  = "test";
+        };
       };
     };
   };