]> err.no Git - scalable-opengroupware.org/commitdiff
fix for SOGo Bug #1051
authorznek <znek@d1b88da0-ebda-0310-925b-ed51d893ca5b>
Fri, 17 Dec 2004 18:17:07 +0000 (18:17 +0000)
committerznek <znek@d1b88da0-ebda-0310-925b-ed51d893ca5b>
Fri, 17 Dec 2004 18:17:07 +0000 (18:17 +0000)
git-svn-id: http://svn.opengroupware.org/SOGo/trunk@479 d1b88da0-ebda-0310-925b-ed51d893ca5b

39 files changed:
OGoContentStore/ChangeLog
OGoContentStore/OCSiCalFieldExtractor.m
OGoContentStore/OGoContentStore.xcode/project.pbxproj
OGoContentStore/Version
OGoContentStore/sql/appointment-create.psql
OGoContentStore/sql/foldertablecreate-helge-privcal.psql
OGoContentStore/sql/generate-folderinfo-sql-for-users.sh
SOGo/SOGo.xcode/project.pbxproj
SOGo/SoObjects/Appointments/SOGoAppointmentFolder.h
SOGo/SoObjects/Appointments/SOGoAppointmentFolder.m
SOGo/SoObjects/Appointments/Version
SOGo/SoObjects/ChangeLog
SOGo/UI/Anais/AnaisAttendeeSelector.m
SOGo/UI/Anais/AnaisAttendeeSelector.wox
SOGo/UI/Anais/ChangeLog
SOGo/UI/Anais/Version
SOGo/UI/SOGoUI/ChangeLog
SOGo/UI/SOGoUI/SOGoAptFormatter.m
SOGo/UI/SOGoUI/Version
SOGo/UI/Scheduler/ChangeLog
SOGo/UI/Scheduler/English.lproj/default.strings
SOGo/UI/Scheduler/GNUmakefile
SOGo/UI/Scheduler/UIxAppointmentEditor.m
SOGo/UI/Scheduler/UIxAppointmentFormatter.h [deleted file]
SOGo/UI/Scheduler/UIxAppointmentFormatter.m [deleted file]
SOGo/UI/Scheduler/UIxAppointmentView.m
SOGo/UI/Scheduler/UIxAppointmentView.wox
SOGo/UI/Scheduler/UIxCalParticipationStatusView.m [new file with mode: 0644]
SOGo/UI/Scheduler/UIxCalParticipationStatusView.wox [new file with mode: 0644]
SOGo/UI/Scheduler/UIxCalScheduleOverview.m
SOGo/UI/Scheduler/UIxCalScheduleOverview.wox
SOGo/UI/Scheduler/UIxCalView.m
SOGo/UI/Scheduler/Version
SOGo/UI/Scheduler/product.plist
SOGoLogic/ChangeLog
SOGoLogic/SOGoAppointment.h
SOGoLogic/SOGoAppointment.m
SOGoLogic/SOGoAppointmentICalRenderer.m
SOGoLogic/Version

index fe5320fabff6ae3dfa03677cfff7915a36a97771..e70e89c593368b2f14501786d030b7894b8e0e2c 100644 (file)
@@ -1,3 +1,12 @@
+2004-12-17  Marcus Mueller  <znek@mulle-kybernetik.com>
+
+       * v0.9.18
+
+       * OCSiCalFieldExtractor.m: extract participants' state
+
+       * sql/generate-folderinfo-sql-for-user.sh, sql/appointment-create.psql,
+         sql/foldertablecreate-helge-privcal.psql: updated with new schema.
+
 2004-12-15  Marcus Mueller  <znek@mulle-kybernetik.com>
 
        * OCSiCalFieldExtractor.m: partmails + cn's are concatenated by '\n'
index c1b9492f879deed3e8bf3b3dfa11b4aa2ba0ac72..6afdac26730b69d6dd58ffef08375227aeb58f32 100644 (file)
@@ -65,12 +65,15 @@ static OCSiCalFieldExtractor *extractor = nil;
 
 - (NSMutableDictionary *)extractQuickFieldsFromEvent:(iCalEvent *)_event {
   NSMutableDictionary *row;
-  NSCalendarDate *startDate, *endDate;
-  NSString       *uid, *title, *location, *status, *accessClass;
-  NSNumber       *sequence;
-  id             organizer;
-  id             participants, partmails;
-  
+  NSCalendarDate      *startDate, *endDate;
+  NSArray             *attendees;
+  NSString            *uid, *title, *location, *status, *accessClass;
+  NSNumber            *sequence;
+  id                  organizer;
+  id                  participants, partmails;
+  NSMutableString     *partstates;
+  unsigned            i, count;
+
   if (_event == nil)
     return nil;
 
@@ -85,10 +88,10 @@ static OCSiCalFieldExtractor *extractor = nil;
   accessClass  = [[_event accessClass] uppercaseString];
   status       = [[_event status] uppercaseString];
 
-  participants = [_event attendees];
-  partmails    = [participants valueForKey:@"rfc822Email"];
+  attendees    = [_event attendees];
+  partmails    = [attendees valueForKey:@"rfc822Email"];
   partmails    = [partmails componentsJoinedByString:@"\n"];
-  participants = [participants valueForKey:@"cn"];
+  participants = [attendees valueForKey:@"cn"];
   participants = [participants componentsJoinedByString:@"\n"];
 
   /* build row */
@@ -123,16 +126,16 @@ static OCSiCalFieldExtractor *extractor = nil;
 
   if ([status isNotNull]) {
     int code = 1;
-
-      if ([status isEqualToString:@"TENTATIVE"])
-          code = 0;
-      else if ([status isEqualToString:@"CANCELLED"])
-          code = 2;
+    
+    if ([status isEqualToString:@"TENTATIVE"])
+      code = 0;
+    else if ([status isEqualToString:@"CANCELLED"])
+      code = 2;
     [row setObject:[NSNumber numberWithInt:code] forKey:@"status"];
   }
   else {
-      /* confirmed by default */
-      [row setObject:[NSNumber numberWithInt:1] forKey:@"status"];
+    /* confirmed by default */
+    [row setObject:[NSNumber numberWithInt:1] forKey:@"status"];
   }
 
   if([accessClass isNotNull] && ![accessClass isEqualToString:@"PUBLIC"]) {
@@ -144,12 +147,28 @@ static OCSiCalFieldExtractor *extractor = nil;
 
   organizer = [_event organizer];
   if (organizer) {
-      NSString *email;
-      
-      email = [organizer valueForKey:@"rfc822Email"];
-      if (email)
-          [row setObject:email forKey:@"orgmail"];
+    NSString *email;
+    
+    email = [organizer valueForKey:@"rfc822Email"];
+    if (email)
+      [row setObject:email forKey:@"orgmail"];
+  }
+  
+  /* construct partstates */
+  count        = [attendees count];
+  partstates   = [[NSMutableString alloc] initWithCapacity:count * 2];
+  for ( i = 0; i < count; i++) {
+    iCalPerson         *p;
+    iCalPersonPartStat stat;
+    
+    p    = [attendees objectAtIndex:i];
+    stat = [p participationStatus];
+    if(i != 0)
+      [partstates appendString:@"\n"];
+    [partstates appendFormat:@"%d", stat];
   }
+  [row setObject:partstates forKey:@"partstates"];
+  [partstates release];
   return row;
 }
 
index 6bf03552b73fa404141ef10282ed3a6bd6ffcf1c..1266e6a7eb565f0f7a8374c1771c17a892238a91 100644 (file)
@@ -73,6 +73,7 @@
                };
                AD0CF94D071FE18800E72147 = {
                        fileEncoding = 5;
+                       indentWidth = 2;
                        isa = PBXFileReference;
                        lastKnownFileType = sourcecode.c.h;
                        path = common.h;
                };
                AD0CF951071FE18800E72147 = {
                        fileEncoding = 5;
+                       indentWidth = 2;
                        isa = PBXFileReference;
                        lastKnownFileType = sourcecode.c.h;
                        path = "EOAdaptorChannel+OCS.h";
                };
                AD0CF952071FE18800E72147 = {
                        fileEncoding = 5;
+                       indentWidth = 2;
                        isa = PBXFileReference;
                        lastKnownFileType = sourcecode.c.objc;
                        path = "EOAdaptorChannel+OCS.m";
                };
                AD0CF953071FE18800E72147 = {
                        fileEncoding = 5;
+                       indentWidth = 2;
                        isa = PBXFileReference;
                        lastKnownFileType = sourcecode.c.h;
                        path = "EOQualifier+OCS.h";
                };
                AD0CF954071FE18800E72147 = {
                        fileEncoding = 5;
+                       indentWidth = 2;
                        isa = PBXFileReference;
                        lastKnownFileType = sourcecode.c.objc;
                        path = "EOQualifier+OCS.m";
                };
                AD0CF95F071FE18800E72147 = {
                        fileEncoding = 5;
+                       indentWidth = 2;
                        isa = PBXFileReference;
                        lastKnownFileType = sourcecode.c.h;
                        path = "NSURL+OCS.h";
                };
                AD0CF960071FE18800E72147 = {
                        fileEncoding = 5;
+                       indentWidth = 2;
                        isa = PBXFileReference;
                        lastKnownFileType = sourcecode.c.objc;
                        path = "NSURL+OCS.m";
                };
                AD0CF961071FE18800E72147 = {
                        fileEncoding = 5;
+                       indentWidth = 2;
                        isa = PBXFileReference;
                        lastKnownFileType = sourcecode.c.objc;
                        path = ocs_cat.m;
                };
                AD0CF962071FE18800E72147 = {
                        fileEncoding = 5;
+                       indentWidth = 2;
                        isa = PBXFileReference;
                        lastKnownFileType = sourcecode.c.objc;
                        path = ocs_ls.m;
                };
                AD0CF963071FE18800E72147 = {
                        fileEncoding = 5;
+                       indentWidth = 2;
                        isa = PBXFileReference;
                        lastKnownFileType = sourcecode.c.objc;
                        path = ocs_mkdir.m;
                };
                AD0CF964071FE18800E72147 = {
                        fileEncoding = 5;
+                       indentWidth = 2;
                        isa = PBXFileReference;
                        lastKnownFileType = sourcecode.c.objc;
                        path = ocs_recreatequick.m;
                };
                AD0CF965071FE18800E72147 = {
                        fileEncoding = 5;
+                       indentWidth = 2;
                        isa = PBXFileReference;
                        lastKnownFileType = sourcecode.c.h;
                        path = OCSChannelManager.h;
                };
                AD0CF966071FE18800E72147 = {
                        fileEncoding = 5;
+                       indentWidth = 2;
                        isa = PBXFileReference;
                        lastKnownFileType = sourcecode.c.objc;
                        path = OCSChannelManager.m;
                };
                AD0CF967071FE18800E72147 = {
                        fileEncoding = 5;
+                       indentWidth = 2;
                        isa = PBXFileReference;
                        lastKnownFileType = sourcecode.c.objc;
                        path = OCSContactFieldExtractor.m;
                };
                AD0CF968071FE18800E72147 = {
                        fileEncoding = 5;
+                       indentWidth = 2;
                        isa = PBXFileReference;
                        lastKnownFileType = sourcecode.c.h;
                        path = OCSContext.h;
                };
                AD0CF969071FE18800E72147 = {
                        fileEncoding = 5;
+                       indentWidth = 2;
                        isa = PBXFileReference;
                        lastKnownFileType = sourcecode.c.objc;
                        path = OCSContext.m;
                };
                AD0CF96A071FE18800E72147 = {
                        fileEncoding = 5;
+                       indentWidth = 2;
                        isa = PBXFileReference;
                        lastKnownFileType = sourcecode.c.h;
                        path = OCSFieldExtractor.h;
                };
                AD0CF96B071FE18800E72147 = {
                        fileEncoding = 5;
+                       indentWidth = 2;
                        isa = PBXFileReference;
                        lastKnownFileType = sourcecode.c.objc;
                        path = OCSFieldExtractor.m;
                };
                AD0CF96C071FE18800E72147 = {
                        fileEncoding = 5;
+                       indentWidth = 2;
                        isa = PBXFileReference;
                        lastKnownFileType = sourcecode.c.h;
                        path = OCSFieldInfo.h;
                };
                AD0CF96D071FE18800E72147 = {
                        fileEncoding = 5;
+                       indentWidth = 2;
                        isa = PBXFileReference;
                        lastKnownFileType = sourcecode.c.objc;
                        path = OCSFieldInfo.m;
                };
                AD0CF96E071FE18800E72147 = {
                        fileEncoding = 5;
+                       indentWidth = 2;
                        isa = PBXFileReference;
                        lastKnownFileType = sourcecode.c.h;
                        path = OCSFolder.h;
                };
                AD0CF96F071FE18800E72147 = {
                        fileEncoding = 5;
+                       indentWidth = 2;
                        isa = PBXFileReference;
                        lastKnownFileType = sourcecode.c.objc;
                        path = OCSFolder.m;
                };
                AD0CF970071FE18800E72147 = {
                        fileEncoding = 5;
+                       indentWidth = 2;
                        isa = PBXFileReference;
                        lastKnownFileType = sourcecode.c.h;
                        path = OCSFolderManager.h;
                };
                AD0CF971071FE18800E72147 = {
                        fileEncoding = 5;
+                       indentWidth = 2;
                        isa = PBXFileReference;
                        lastKnownFileType = sourcecode.c.objc;
                        path = OCSFolderManager.m;
                };
                AD0CF972071FE18800E72147 = {
                        fileEncoding = 5;
+                       indentWidth = 2;
                        isa = PBXFileReference;
                        lastKnownFileType = sourcecode.c.h;
                        path = OCSFolderType.h;
                };
                AD0CF973071FE18800E72147 = {
                        fileEncoding = 5;
+                       indentWidth = 2;
                        isa = PBXFileReference;
                        lastKnownFileType = sourcecode.c.objc;
                        path = OCSFolderType.m;
                };
                AD0CF974071FE18800E72147 = {
                        fileEncoding = 5;
+                       indentWidth = 2;
                        isa = PBXFileReference;
                        lastKnownFileType = sourcecode.c.h;
                        path = OCSiCalFieldExtractor.h;
                };
                AD0CF975071FE18800E72147 = {
                        fileEncoding = 5;
+                       indentWidth = 2;
                        isa = PBXFileReference;
                        lastKnownFileType = sourcecode.c.objc;
                        path = OCSiCalFieldExtractor.m;
                                AD0CF952071FE18800E72147,
                                AD0CF954071FE18800E72147,
                        );
+                       indentWidth = 2;
                        isa = PBXGroup;
                        name = Classes;
                        refType = 4;
                                AD0CF951071FE18800E72147,
                                AD0CF953071FE18800E72147,
                        );
+                       indentWidth = 2;
                        isa = PBXGroup;
                        name = Headers;
                        path = "";
                };
                AD0CF9CC071FE4A400E72147 = {
                        fileEncoding = 4;
+                       indentWidth = 2;
                        isa = PBXFileReference;
                        lastKnownFileType = sourcecode.c.h;
                        path = OCSStringFormatter.h;
index f48344243f60816736be5e01c78d581af4e39c66..1adba52a3a88ed791ca0f7bfbe16ad4408676d4d 100644 (file)
@@ -2,8 +2,9 @@
 
 MAJOR_VERSION=0
 MINOR_VERSION=9
-SUBMINOR_VERSION:=17
+SUBMINOR_VERSION:=18
 
+# v0.9.18 requires libNGiCal       v4.5.38
 # v0.9.17 requires libNGiCal       v4.5.37
 # v0.9.11 requires libFoundation   v1.0.63
 # v0.9.11 requires libNGExtensions v4.3.125
index a928399868f25fade86509acc48bc41959565b6d..7b280be7731c268d9c75a8128c0a34e9f35236cc 100644 (file)
@@ -12,8 +12,13 @@ CREATE TABLE %s_quick (
   participants VARCHAR(100000) NOT NULL, -- the CNs of the participants
   isallday     INT             NULL,
   iscycle      INT             NULL,     -- client needs to fetch to resolve
+  ispublic     INT             NOT NULL,
+  status       INT             NOT NULL,
+  isopaque     INT             NULL,
   location     VARCHAR(256)    NULL,
+  orgmail      VARCHAR(256)    NULL,
   partmails    VARCHAR(100000) NOT NULL, -- the emails of the participants
+  partstates   VARCHAR(256)    NOT NULL, -- the status of each participant
   sequence     INT             NULL      -- the iCal sequence
 );
 
index 11334170d56191a14941a1110987a39f8caee47b..558a714a60948a50963eeb74af1552adf6227c22 100644 (file)
@@ -21,6 +21,7 @@ CREATE TABLE SOGo_helge_privcal_quick (
   location     VARCHAR(256)    NULL,
   orgmail      VARCHAR(256)    NULL,
   partmails    VARCHAR(100000) NOT NULL, -- the emails of the participants
+  partstates   VARCHAR(256)    NOT NULL, -- the status of each participant
   sequence     INT             NULL      -- the iCal sequence
 );
 
index 5ad0df6566abfd540cf620262b877c80ddc10824..2b054a3a6e600c47e4bf5fd7272804aa60682bc4 100755 (executable)
@@ -82,6 +82,7 @@ CREATE TABLE SOGo_${USER_TABLE}_privcal_quick (
   location     VARCHAR(256)    NULL,
   orgmail      VARCHAR(256)    NULL,
   partmails    VARCHAR(100000) NOT NULL, -- the emails of the participants
+  partstates   VARCHAR(256)    NOT NULL, -- the status of each participant
   sequence     INT             NULL      -- the iCal sequence
 );
 
index 3ea15f34dc827d7d676a4cf6a48d2129cf98fc86..8a4c697fd511f1fa1caed6336e9c838dce70bd92 100644 (file)
                                E87208F40692E3D30099CBBD,
                                E87208FA0692E3D30099CBBD,
                                E87208FB0692E3D30099CBBD,
+                               AD273D4D077315640064794B,
+                               AD273D4C077315640064794B,
                        );
                        isa = PBXGroup;
                        name = Appointment;
                        sourceTree = "<group>";
                        tabWidth = 2;
                };
+               AD273D4C077315640064794B = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = text.xml;
+                       path = UIxCalParticipationStatusView.wox;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
+               AD273D4D077315640064794B = {
+                       fileEncoding = 4;
+                       isa = PBXFileReference;
+                       lastKnownFileType = sourcecode.c.objc;
+                       path = UIxCalParticipationStatusView.m;
+                       refType = 4;
+                       sourceTree = "<group>";
+               };
                AD2C74A1071A9FF70087E027 = {
                        fileEncoding = 5;
                        isa = PBXFileReference;
                        refType = 4;
                        sourceTree = "<group>";
                };
-               E87208F50692E3D30099CBBD = {
-                       fileEncoding = 5;
-                       indentWidth = 2;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.h;
-                       path = UIxAppointmentFormatter.h;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
-               E87208F60692E3D30099CBBD = {
-                       fileEncoding = 5;
-                       indentWidth = 2;
-                       isa = PBXFileReference;
-                       lastKnownFileType = sourcecode.c.objc;
-                       path = UIxAppointmentFormatter.m;
-                       refType = 4;
-                       sourceTree = "<group>";
-               };
                E87208F70692E3D30099CBBD = {
                        fileEncoding = 5;
                        indentWidth = 2;
                        children = (
                                E87208900692E3D30099CBBD,
                                E87208E40692E3D30099CBBD,
-                               E87208F50692E3D30099CBBD,
-                               E87208F60692E3D30099CBBD,
                                E87209060692E3D30099CBBD,
                                E87209070692E3D30099CBBD,
                                AD5ED1AE06B1768900E3EC4B,
index 882018c07379c747b1b4fce3b77122723d5c9547..2e62d93236ea64a0a9c9794d58beb2f9c500e1c6 100644 (file)
 - (NSArray *)fetchCoreInfosFrom:(NSCalendarDate *)_startDate
   to:(NSCalendarDate *)_endDate;
 
+- (NSArray *)fetchOverviewInfosFromFolder:(OCSFolder *)_folder
+  from:(NSCalendarDate *)_startDate
+  to:(NSCalendarDate *)_endDate;
+
+- (NSArray *)fetchOverviewInfosFrom:(NSCalendarDate *)_startDate
+  to:(NSCalendarDate *)_endDate;
+
 /* URL generation */
 
 - (NSString *)baseURLForAptWithUID:(NSString *)_uid inContext:(id)_ctx;
index a5371bff9df526381d713e72f45c6da06a1eebc7..9412ffb57d0673fd825264ba5d64289a0f953bc1 100644 (file)
@@ -208,21 +208,52 @@ static NSTimeZone *MET = nil;
   return records;
 }
 
+- (NSArray *)fetchOverviewInfosFromFolder:(OCSFolder *)_folder
+  from:(NSCalendarDate *)_startDate
+  to:(NSCalendarDate *)_endDate
+{
+  static NSArray *infos = nil;
+  if(!infos) {
+    infos = [[NSArray arrayWithObjects:@"uid", @"startdate", @"enddate",
+                                       @"title", @"location", @"orgmail",
+                                       @"status", @"ispublic", @"iscycle",
+                                       @"isallday",
+                                       nil] retain];
+  }
+  return [self fetchFields:infos
+               fromFolder:_folder
+               from:_startDate
+               to:_endDate];
+}
+
+- (NSArray *)fetchOverviewInfosFrom:(NSCalendarDate *)_startDate
+  to:(NSCalendarDate *)_endDate
+{
+  OCSFolder *folder;
+  
+  if ((folder = [self ocsFolder]) == nil) {
+    [self errorWithFormat:@"(%s): missing folder for fetch!",
+                            __PRETTY_FUNCTION__];
+    return nil;
+  }
+  return [self fetchOverviewInfosFromFolder:folder from:_startDate to:_endDate];
+}
+
 - (NSArray *)fetchCoreInfosFromFolder:(OCSFolder *)_folder
   from:(NSCalendarDate *)_startDate
   to:(NSCalendarDate *)_endDate 
 {
-  static NSArray *coreInfos = nil;
-  if(!coreInfos) {
-    coreInfos = [[NSArray arrayWithObjects:@"uid", @"startdate", @"enddate",
-                                           @"title", @"participants",
-                                           @"location", @"isallday",
-                                           @"iscycle", @"partmails",
-                                           @"sequence", @"ispublic",
-                                           @"isopaque", @"status", @"orgmail",
-                                           nil] retain];
+  static NSArray *infos = nil;
+  if(!infos) {
+    infos = [[NSArray arrayWithObjects:@"uid", @"startdate", @"enddate",
+                                       @"title", @"location", @"orgmail",
+                                       @"status", @"ispublic", @"iscycle",
+                                       @"isallday", @"isopaque",
+                                       @"participants", @"partmails",
+                                       @"partstates", @"sequence",
+                                       nil] retain];
   }
-  return [self fetchFields:coreInfos
+  return [self fetchFields:infos
                fromFolder:_folder
                from:_startDate
                to:_endDate];
@@ -236,7 +267,7 @@ static NSTimeZone *MET = nil;
   
   if ((folder = [self ocsFolder]) == nil) {
     [self errorWithFormat:@"(%s): missing folder for fetch!",
-            __PRETTY_FUNCTION__];
+                            __PRETTY_FUNCTION__];
     return nil;
   }
   return [self fetchCoreInfosFromFolder:folder from:_startDate to:_endDate];
index 63f19036a23f9692404dde6128fc0c0242764ee3..ed0844b5214e3d239647af679740e1007b124006 100644 (file)
@@ -1,6 +1,6 @@
 # Version file
 
-SUBMINOR_VERSION:=22
+SUBMINOR_VERSION:=23
 
 # v0.9.19 requires NGiCal  v4.5.36
 # v0.9.13 requires libSOGo v0.9.26
index 9818b304b5e8d2a34c85ac4792bbed685381d794..104f80edb97a2711ccb5690311b44ba055bbf044 100644 (file)
@@ -1,3 +1,9 @@
+2004-12-17  Marcus Mueller  <znek@mulle-kybernetik.com>
+
+       * Appointments/SOGoAppointmentFolder.[hm]: added "partstates" to
+         coreInfos for fetching. Also added new API to fetch a stripped down
+         version of coreInfos, suitable for overviews. (v0.9.23)
+
 2004-12-15  Marcus Mueller  <znek@mulle-kybernetik.com>
 
        * Appointments/SOGoAppointmentFolder.m: default redirect is now
index d8474b2ca3dc71f8db7bc233e4eb3b7cde15ad9e..728c2f13b7200f633e61e99559901f061f50c6a4 100644 (file)
@@ -168,22 +168,25 @@ static BOOL debugOn = NO;
   return [self hasNoAttendees] && [[self emailForUser] length] > 0 ? YES : NO;
 }
 
-/* email, cn */
+/* email, stat, cn */
 
-- (NSString *)combinedCNAndEmailForUser {
+- (NSString *)combinedInfoForUser {
   NSString *e, *c;
 
   e = [self emailForUser];
   c = [self cnForUser];
-  return [[e stringByAppendingString:@";"] stringByAppendingString:c];
+  return [[e stringByAppendingString:@";0;"] stringByAppendingString:c];
 }
 
-- (NSString *)combinedCNAndEmail {
-  NSString *e, *c;
+- (NSString *)combinedInfo {
+  iCalPerson *p;
+  NSString   *e, *stat, *c;
   
-  e = [[self attendee] rfc822Email];
-  c = [[self attendee] cnForDisplay];
-  return [[e stringByAppendingString:@";"] stringByAppendingString:c];
+  p    = [self attendee];
+  e    = [p rfc822Email];
+  c    = [p cnForDisplay];
+  stat = [NSString stringWithFormat:@";%d;", [p participationStatus]];
+  return [[e stringByAppendingString:stat] stringByAppendingString:c];
 }
 
 /* id accessors */
@@ -231,14 +234,26 @@ static BOOL debugOn = NO;
     pString = [_values objectAtIndex:i];
     if ([pString length] == 0)
       continue;
-    
-    /* delimiter between email and cn */
+
+    p = [[iCalPerson alloc] init];
+
+    /* sample: 'test.et.di.cete-lyon@equipement.gouv.fr;1;test' */
+    /* delimiter between email and partStat */
     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:NSMaxRange(r)];
-      if ([cn length] == 0) cn = nil;
+      
+      pString = [pString substringFromIndex:NSMaxRange(r)];
+      /* delimiter between partStat and CN */
+      r = [pString rangeOfString:@";"];
+      if (r.length > 0) {
+        NSString *stat;
+        
+        stat  = [pString substringToIndex:r.location];
+        [p setParticipationStatus:[stat intValue]];
+        cn    = [pString substringFromIndex:NSMaxRange(r)];
+        if ([cn length] == 0) cn = nil;
+      }
     }
     else {
       email = pString;
@@ -250,7 +265,6 @@ static BOOL debugOn = NO;
       cn = [um getCNForUID:[um getUIDForEmail:email]];
     }
     
-    p = [[iCalPerson alloc] init];
     [p setEmail:[@"mailto:" stringByAppendingString:email]];
     if ([cn isNotNull]) [p setCn:cn];
     
@@ -305,7 +319,7 @@ static BOOL debugOn = NO;
       @"  checkbox = document.createElement('input');\n"
       @"  checkbox.setAttribute('type', 'checkbox');\n"
       @"  checkbox.setAttribute('checked', 'checked');\n"
-      @"  checkbox.setAttribute('value', email + ';' + cn);\n"
+      @"  checkbox.setAttribute('value', email + ';0;' + cn);\n"
       @"  checkbox.setAttribute('id', email);\n"
       @"  checkbox.setAttribute('name', tableId);\n"
       @"  td.appendChild(checkbox);\n"
index 893390eeef62665f29b85d379357ac84bc3e77e5..410f74d9ad355e31fb50d18536977afd2a3e540c 100644 (file)
@@ -27,7 +27,7 @@
       <tr>
         <td><input type="checkbox"
                    checked="YES"
-                   var:value="combinedCNAndEmailForUser"
+                   var:value="combinedInfoForUser"
                    var:id="emailForUser"
                    var:name="checkboxId"
              /></td>
@@ -40,7 +40,7 @@
         <var:if condition="withCN">
           <td><input type="checkbox"
                      checked="YES"
-                     var:value="combinedCNAndEmail"
+                     var:value="combinedInfo"
                      var:id="attendee.rfc822Email"
                      var:name="checkboxId"
               /></td>
index 78c05da315db4393b9787e75d41f5b5358902a92..a6037246dffdb23250dee7b64644595fa0b3efca 100644 (file)
@@ -1,3 +1,7 @@
+2004-12-17  Marcus Mueller  <znek@mulle-kybernetik.com>
+
+       * AnaisAttendeeSelector.m: preserve participation status (v0.9.18)
+
 2004-10-20  Marcus Mueller  <znek@mulle-kybernetik.com>
 
        * AnaisAttendeeSelector.m: provide proper unescaping of special HTML
index f929c4cecad4e6140b8b068a09cf930bdbb54abb..e138e47c3c8a7f405acf1d7b34476b2bc10adeff 100644 (file)
@@ -1,3 +1,3 @@
 # $Id: Version 165 2004-08-05 17:55:50Z znek $
 
-SUBMINOR_VERSION:=17
+SUBMINOR_VERSION:=18
index f220d3229a500ce3920765bc8e293d0dfa12700f..3a950e3d12e114530cbe42e2d1f27d51cb571933 100644 (file)
@@ -1,3 +1,8 @@
+2004-12-17  Marcus Mueller  <znek@mulle-kybernetik.com>
+
+       * SOGoAptFormatter.m: remove "appointment" prefix from tooltips
+         (v0.9.22)
+
 2004-12-13  Marcus Mueller  <znek@mulle-kybernetik.com>
 
        * SOGoAptFormatter.[hm]: new option for formatter (v0.9.21)
index 0694429a080dd216e257eaf0e5cef47b5548cd3d..e468d78321bfc379d1fdbe7533935e8a2ddbd85a 100644 (file)
     spansRange = ![endDate isEqualToDate:startDate];
   }
   aptDescr = [NSMutableString stringWithCapacity:60];
-  [aptDescr appendString:@"appointment"];
-  [aptDescr appendFormat:@"\n%02i:%02i",
+  [aptDescr appendFormat:@"%02i:%02i",
            [startDate hourOfDay],
            [startDate minuteOfHour]];
   if (spansRange) {
     spansRange = ![endDate isEqualToDate:startDate];
   }
   aptDescr = [NSMutableString stringWithCapacity:25];
-  [aptDescr appendString:@"appointment"];
-  [aptDescr appendFormat:@"\n%02i:%02i",
+  [aptDescr appendFormat:@"%02i:%02i",
     [startDate hourOfDay],
     [startDate minuteOfHour]];
   if (spansRange) {
index c0af8cd7f5336ad16e2f3a7d80d15fda7ff77a2b..dd5eff262b3a74eb473420a31961e0d3576ffe48 100644 (file)
@@ -1,5 +1,5 @@
 # $Id$
 
-SUBMINOR_VERSION:=21
+SUBMINOR_VERSION:=22
 
 # v0.9.18 requires NGExtensions v4.5.136
index 1284cce43bdcc453cfc5228842c578e9be08a9ea..5e15dc34a8efa80da5ea1be9d7cd3f8a23d7798a 100644 (file)
@@ -1,3 +1,30 @@
+2004-12-17  Marcus Mueller  <znek@mulle-kybernetik.com>
+
+       * v0.9.104
+
+       * GNUmakefile: removed UIxAppointmentFormatter
+
+       * UIxAppointmentFormatter.[hm]: removed, never in use
+
+       * UIxCalParticipationStatusView.[wox,m]: new view to display localized
+         participation status
+
+       * UIxCalView.m: fetch OverviewInfos instead of CoreInfos (should be
+         faster)
+
+       * UIxCalScheduleOverview.[wox,m]: completed the schedule overview,
+         display participation state for all participants.
+
+       * product.plist: renamed "reject" to "decline" and moved from
+         UIxAppointmentView to UIxAppointmentEditor.
+
+       * UIxAppointmentView.m: removed "accept" and "reject" action stubs
+
+       * UIxAppointmentEditor.[wox,m]: implemented "accept" and "decline".
+         Changed iCal template a bit, particularly removed getOrganizer -
+         with every save the organizer was changed also which was horribly
+         wrong.
+
 2004-12-16  Marcus Mueller  <znek@mulle-kybernetik.com>
 
        * v0.9.103
index fca12bbe9bc8afd5e63f9f9f3f41bb2f42006e73..f1c14fdc29f989ca512efaa013e6984f98b17dac 100644 (file)
@@ -95,7 +95,8 @@
 "sched_startDateFormat" = "%d.%m. %H:%M";
 "action"               = "Actions";
 "accept"               = "Accept";
-"reject"               = "Reject";
+"decline"              = "Decline";
+"more participants"     = "more participants";
 
 
 /* Appointments */
 "Title"                        = "Title";
 "Name"                 = "Name";
 "Email"                        = "Email";
+"Status"               = "Status";
 "Location"             = "Location";
 "Priority"             = "Priority";
 "Categories"           = "Categories";
 /* text used in overviews and tooltips */
 "private appointment"  = "Private appointment";
 
+/* Appointments (participation state) */
+
+"partStat_NEEDS-ACTION"        = "Not decided, yet";
+"partStat_ACCEPTED"    = "Accepted";
+"partStat_DECLINED"    = "Declined";
+"partStat_TENTATIVE"   = "Tentative";
+"partStat_DELEGATED"   = "Delegated";
+"partStat_OTHER"       = "???";
+
 
 /* Searching */
 
index ffd914f70776610d6e93a069c55b34a9c73baae1..f5db8afe16d589b451b1fd07280e6fcbde7d9c28 100644 (file)
@@ -10,7 +10,6 @@ SchedulerUI_LANGUAGES = English French
 
 SchedulerUI_OBJC_FILES =               \
        SchedulerUIProduct.m            \
-       UIxAppointmentFormatter.m       \
        iCalPerson+UIx.m                \
        NSCalendarDate+UIx.m            \
        SOGoAppointment+UIx.m           \
@@ -36,7 +35,7 @@ SchedulerUI_OBJC_FILES =              \
        UIxCalYearOverview.m            \
        UIxCalInlineMonthOverview.m     \
        UIxAppointmentView.m            \
-       UIxAppointmentPrintview.m               \
+       UIxAppointmentPrintview.m       \
        UIxAppointmentEditor.m          \
        UIxCalSelectTab.m               \
        UIxCalDateLabel.m               \
@@ -48,39 +47,41 @@ SchedulerUI_OBJC_FILES =            \
        UIxTimeDateControl.m            \
        UIxCalInlineAptView.m           \
        UIxCalScheduleOverview.m        \
+       UIxCalParticipationStatusView.m \
 
 SchedulerUI_RESOURCE_FILES += \
        Version         \
        product.plist
 
-SchedulerUI_RESOURCE_FILES +=          \
-       UIxAptTableView.wox             \
-       UIxCalDayOverview.wox           \
-       UIxCalDayChartview.wox          \
-       UIxCalDayListview.wox           \
-       UIxCalDayPrintview.wox          \
-       UIxCalWeekOverview.wox          \
-       UIxCalWeekChartview.wox         \
-       UIxCalWeekListview.wox          \
-       UIxCalWeekColumnsview.wox       \
-       UIxCalWeekPrintview.wox         \
-       UIxCalMonthOverview.wox         \
-       UIxCalMonthPrintview.wox        \
-       UIxCalYearOverview.wox          \
-       UIxCalInlineMonthOverview.wox   \
-       UIxAppointmentView.wox          \
+SchedulerUI_RESOURCE_FILES +=                  \
+       UIxAptTableView.wox                     \
+       UIxCalDayOverview.wox                   \
+       UIxCalDayChartview.wox                  \
+       UIxCalDayListview.wox                   \
+       UIxCalDayPrintview.wox                  \
+       UIxCalWeekOverview.wox                  \
+       UIxCalWeekChartview.wox                 \
+       UIxCalWeekListview.wox                  \
+       UIxCalWeekColumnsview.wox               \
+       UIxCalWeekPrintview.wox                 \
+       UIxCalMonthOverview.wox                 \
+       UIxCalMonthPrintview.wox                \
+       UIxCalYearOverview.wox                  \
+       UIxCalInlineMonthOverview.wox           \
+       UIxAppointmentView.wox                  \
        UIxAppointmentPrintview.wox             \
-       UIxAppointmentEditor.wox        \
-       UIxCalSelectTab.wox             \
-       UIxCalDateLabel.wox             \
-       UIxCalBackForthNavView.wox      \
-       UIxAppointmentProposal.wox      \
-       UIxDatePicker.wox               \
-       UIxDatePickerScript.wox         \
-       UIxTimeSelector.wox             \
-       UIxTimeDateControl.wox          \
-       UIxCalInlineAptView.wox         \
-       UIxCalScheduleOverview.wox      \
+       UIxAppointmentEditor.wox                \
+       UIxCalSelectTab.wox                     \
+       UIxCalDateLabel.wox                     \
+       UIxCalBackForthNavView.wox              \
+       UIxAppointmentProposal.wox              \
+       UIxDatePicker.wox                       \
+       UIxDatePickerScript.wox                 \
+       UIxTimeSelector.wox                     \
+       UIxTimeDateControl.wox                  \
+       UIxCalInlineAptView.wox                 \
+       UIxCalScheduleOverview.wox              \
+       UIxCalParticipationStatusView.wox       \
 
 SchedulerUI_RESOURCE_FILES += \
        images/next_week.gif                    \
index f595fa67c86d37ed1c1886b9bbc73e6f036300cc..4ed4388dcc0d04452a84ee1074cb1050f332460c 100644 (file)
@@ -56,7 +56,6 @@
 
 - (NSString *)_completeURIForMethod:(NSString *)_method;
 
-- (iCalPerson *)getOrganizer;
 - (NSArray *)getICalPersonsFromFormValues:(NSArray *)_values
   treatAsResource:(BOOL)_isResource;
 
 - (NSString *)iCalResourcesStringFromQueryParameters;
 - (NSString *)iCalStringFromQueryParameter:(NSString *)_qp
               format:(NSString *)_format;
+- (NSString *)iCalOrganizerString;
+
+- (id)acceptOrDeclineAction:(BOOL)_accept;
+
 @end
 
 #include "common.h"
     @"BEGIN:VEVENT\r\n"
     @"UID:%@\r\n"
     @"CLASS:PUBLIC\r\n"
-    @"STATUS:CONFIRMED\r\n"
+    @"STATUS:CONFIRMED\r\n" /* confirmed by default */
     @"DTSTAMP:%@\r\n"
     @"DTSTART:%@\r\n"
     @"DTEND:%@\r\n"
     @"TRANSP:%@\r\n"
     @"SEQUENCE:1\r\n"
     @"PRIORITY:5\r\n"
-    @"%@"
+    @"%@"                   /* organizer */
+    @"%@"                   /* participants and resources */
     @"END:VEVENT\r\n"
     @"END:VCALENDAR";
 
   lEndDate   = [lStartDate dateByAddingYears:0 months:0 days:0
                            hours:0 minutes:minutes seconds:0];
   
-  s = [self iCalParticipantsAndResourcesStringFromQueryParameters];
-  template = [NSString stringWithFormat:iCalStringTemplate,
-                        [[self clientObject] nameInContainer],
-                        [[NSCalendarDate date] icalString],
-                        [lStartDate icalString],
-             [lEndDate icalString],
-             [self transparency],
-             s];
+  s          = [self iCalParticipantsAndResourcesStringFromQueryParameters];
+  template   = [NSString stringWithFormat:iCalStringTemplate,
+                                                     [[self clientObject] nameInContainer],
+                                                     [[NSCalendarDate date] icalString],
+                                          [lStartDate icalString],
+                                          [lEndDate icalString],
+                                          [self transparency],
+                                          [self iCalOrganizerString],
+                                          s];
   return template;
 }
 
   return iCalRep;
 }
 
+- (NSString *)iCalOrganizerString {
+  static NSString *fmt = @"ORGANIZER;CN=\"%@\":mailto:%@\r\n";
+  return [NSString stringWithFormat:fmt,
+                                      [self cnForUser],
+                                      [self emailForUser]];
+}
+
+#if 0
+- (iCalPerson *)getOrganizer {
+  iCalPerson *p;
+  NSString   *emailProp;
+  
+  emailProp = [@"mailto:" stringByAppendingString:[self emailForUser]];
+  p = [[[iCalPerson alloc] init] autorelease];
+  [p setEmail:emailProp];
+  [p setCn:[self cnForUser]];
+  return p;
+}
+#endif
+
+
 /* helper */
 
 - (NSString *)_completeURIForMethod:(NSString *)_method {
   return date;
 }
 
-- (iCalPerson *)getOrganizer {
-  iCalPerson *p;
-  NSString   *emailProp;
-  
-  emailProp = [@"mailto:" stringByAppendingString:[self emailForUser]];
-  p = [[[iCalPerson alloc] init] autorelease];
-  [p setEmail:emailProp];
-  [p setCn:[self cnForUser]];
-  return p;
-}
-
 - (NSArray *)getICalPersonsFromFormValues:(NSArray *)_values
   treatAsResource:(BOOL)_isResource
 {
       : lResources;
   }
   [_appointment setAttendees:attendees];
-  
+
+#if 0
   [_appointment setOrganizer:[self getOrganizer]];
+#endif
 }
 
 - (void)loadValuesFromICalString:(NSString *)_ical {
 
 - (id)saveAction {
   SOGoAppointment *apt;
-  NSException     *ex;
+  iCalPerson      *p;
   NSString        *content;
+  NSException     *ex;
   
   if (![self isWriteableClientObject]) {
     /* return 400 == Bad Request */
   }
   
   [self saveValuesIntoAppointment:apt];
+  p = [apt findParticipantWithEmail:[self emailForUser]];
+  if (p) {
+    [p setParticipationStatus:iCalPersonPartStatAccepted];
+  }
+
   content = [apt iCalString];
   [apt release]; apt = nil;
   
   return [self redirectToLocation:[self _completeURIForMethod:@".."]];
 }
 
+- (id)acceptAction {
+  return [self acceptOrDeclineAction:YES];
+}
+
+- (id)declineAction {
+  return [self acceptOrDeclineAction:NO];
+}
+
+- (id)acceptOrDeclineAction:(BOOL)_accept {
+  SOGoAppointment *apt;
+  iCalPerson      *p;
+  NSString        *iCal, *content;
+  NSException     *ex;
+
+  if (![self isWriteableClientObject]) {
+    /* 400 == Bad Request */
+    return [NSException exceptionWithHTTPStatus:400
+                        reason:@"method cannot be invoked on "
+                               @"the specified object"];
+  }
+  iCal = [[self clientObject] valueForKey:@"iCalString"];
+  apt  = [[SOGoAppointment alloc] initWithICalString:iCal];
+  if (apt == nil) {
+    /* 500 == Internal Server Error */
+    return [NSException exceptionWithHTTPStatus:500
+                        reason:@"unable to parse appointment"];
+  }
+  
+  p = [apt findParticipantWithEmail:[self emailForUser]];
+  if (!p) {
+    /* 404 == Not found */
+    return [NSException exceptionWithHTTPStatus:404
+                        reason:@"user does not participate in this "
+                               @"appointment"];
+  }
+  if(_accept)
+    [p setParticipationStatus:iCalPersonPartStatAccepted];
+  else
+    [p setParticipationStatus:iCalPersonPartStatDeclined];
+
+  content = [apt iCalString];
+  [apt release];
+  
+  if (content == nil) {
+    /* 500 == Internal Server Error */
+    return [NSException exceptionWithHTTPStatus:500
+                        reason:@"Could not create iCalendar data ..."];
+  }
+  
+  ex = [[self clientObject] saveContentString:content];
+  if (ex != nil) {
+    /* 500 == Internal Server Error */
+    return [NSException exceptionWithHTTPStatus:500
+                        reason:[ex reason]];
+  }
+  
+  return [self redirectToLocation:[self _completeURIForMethod:@".."]];
+}
+
 @end /* UIxAppointmentEditor */
diff --git a/SOGo/UI/Scheduler/UIxAppointmentFormatter.h b/SOGo/UI/Scheduler/UIxAppointmentFormatter.h
deleted file mode 100644 (file)
index 9a4d9f3..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
-  Copyright (C) 2004 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.
-*/
-// $Id$
-
-#ifndef __UIxAppointmentFormatter_H__
-#define __UIxAppointmentFormatter_H__
-
-#import <Foundation/NSFormatter.h>
-
-/*
-  Formatter to format appointment-dicts to readable strings:
-
-  %[(dateFormat)]S
-             - startDate formatted with the dateFormat string
-             - if no dateFormat is defined, the default formats are used
-             - !!! dont forget the ()brakes !!!
-  %[(dateFormat)]E
-             - endDate formatted with the dateFormat string
-             - if no dateFormat is defined, the default formats are used
-             - !!! dont forget the ()brakes !!!
-
-  %[length]T - title with the specified length
-             - if title has more chars than length overLengthString is appended
-             - if no length is defined, no limit is set
-
-  %[max]P    - participants
-             - if more than max participants at appointment
-               moreParticipantsString is appended
-             - if no max defined no limit is set
-
-  %[length]L - location
-             - if location has more chars than length overLengthString is
-               appended
-             - if no length is defined, no limit is set
-
-  Example:
-  format: @"%S - %E, \n%T";
-*/
-
-@class NSCalendarDate;
-
-@interface UIxAppointmentFormatter : NSFormatter
-{
-@protected
-  NSString        *formatString;           // default: @"%S - %E, \n%T"
-  
-  NSString        *dateFormat;             // default: @"%H:%M"
-  NSString        *otherDayDateFormat;     // default: @"%H:%M(%m-%d)"
-  NSString        *otherYearDateFormat;    // default: @"%H:%M(%Y-%m-%d)"
-
-  NSString        *toLongString;           // default: @".."
-  NSString        *moreParticipantsString; // default: @"..."
-  NSString        *participantsSeparator;  // default: @", "
-
-  NSCalendarDate  *relationDate;           // if nil, dateFormat used as format
-  // to know whether its the same day, the same year or another year
-
-  BOOL            showFullNames; // try to show full names of participants
-}
-
-/* init */
-
-- (id)initWithFormat:(NSString *)_format;
-+ (UIxAppointmentFormatter *)formatterWithFormat:(NSString *)_format;
-+ (UIxAppointmentFormatter *)formatter;
-
-/* accessors */
-
-- (void)setFormat:(NSString *)_format;
-- (NSString *)format;
-
-- (void)setDateFormat:(NSString *)_format;
-- (NSString *)dateFormat;
-
-- (void)setOtherDayDateFormat:(NSString *)_format;
-- (NSString *)otherDayDateFormat;
-
-- (void)setOtherYearDateFormat:(NSString *)_format;
-- (NSString *)otherYearDateFormat;
-
-- (void)setToLongString:(NSString *)_toLong;
-- (NSString *)toLongString;
-
-- (void)setMoreParticipantsString:(NSString *)_more;
-- (NSString *)moreParticipantsString;
-
-- (void)setParticipantsSeparator:(NSString *)_sep;
-- (NSString *)participantsSeparator;
-
-- (void)setRelationDate:(NSCalendarDate *)_relation;
-- (NSCalendarDate *)relationDate;
-
-- (void)setShowFullNames:(BOOL)_flag;
-- (BOOL)showFullNames;
-
-/* easy switches */
-
-/* this resets the date format */
-- (void)switchToAMPMTimes:(BOOL)_showAMPM;
-
-@end
-
-#endif
diff --git a/SOGo/UI/Scheduler/UIxAppointmentFormatter.m b/SOGo/UI/Scheduler/UIxAppointmentFormatter.m
deleted file mode 100644 (file)
index d90a35a..0000000
+++ /dev/null
@@ -1,452 +0,0 @@
-/*
-  Copyright (C) 2004 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.
-*/
-// $Id$
-
-#include "UIxAppointmentFormatter.h"
-#import <Foundation/Foundation.h>
-#import <NGExtensions/NGExtensions.h>
-#import <EOControl/EOControl.h>
-
-@implementation UIxAppointmentFormatter
-
-- (id)init {
-  if ((self = [super init])) {
-    [self setFormat:@"%S - %E, \n%T"];
-    [self setDateFormat:@"%H:%M"];
-    [self setOtherDayDateFormat:@"%H:%M(%m-%d)"];
-    [self setOtherYearDateFormat:@"%H:%M(%Y-%m-%d)"];
-    [self setToLongString:@".."];
-    [self setMoreParticipantsString:@"..."];
-    [self setParticipantsSeparator:@", "];
-    [self setRelationDate:nil];
-    self->showFullNames = NO;
-  }
-  return self;
-}
-
-- (id)initWithFormat:(NSString *)_format {
-  if ((self = [self init])) {
-    [self setFormat:_format];
-  }
-  return self;
-}
-
-+ (UIxAppointmentFormatter *)formatterWithFormat:(NSString *)_format {
-  return AUTORELEASE([(UIxAppointmentFormatter *)[UIxAppointmentFormatter alloc]
-                                                 initWithFormat:_format]);
-}
-
-+ (UIxAppointmentFormatter *)formatter {
-  return AUTORELEASE([[UIxAppointmentFormatter alloc] init]);
-}
-
-- (void)dealloc {
-  RELEASE(self->formatString);
-  RELEASE(self->dateFormat);
-  RELEASE(self->otherDayDateFormat);
-  RELEASE(self->otherYearDateFormat);
-  RELEASE(self->toLongString);
-  RELEASE(self->moreParticipantsString);
-  RELEASE(self->participantsSeparator);
-  RELEASE(self->relationDate);
-
-  [super dealloc];
-}
-
-// accessors
-
-- (void)setFormat:(NSString *)_format {
-  ASSIGN(self->formatString,_format);
-}
-- (NSString *)format {
-  return self->formatString;
-}
-
-- (void)setDateFormat:(NSString *)_format {
-  ASSIGN(self->dateFormat,_format);
-}
-- (NSString *)dateFormat {
-  return self->dateFormat;
-}
-
-- (void)setOtherDayDateFormat:(NSString *)_format {
-  ASSIGN(self->otherDayDateFormat,_format);
-}
-- (NSString *)otherDayDateFormat {
-  return self->otherDayDateFormat;
-}
-
-- (void)setOtherYearDateFormat:(NSString *)_format {
-  ASSIGN(self->otherYearDateFormat,_format);
-}
-- (NSString *)otherYearDateFormat {
-  return self->otherYearDateFormat;
-}
-
-- (void)setToLongString:(NSString *)_toLong {
-  ASSIGN(self->toLongString,_toLong);
-}
-- (NSString *)toLongString {
-  return self->toLongString;
-}
-
-- (void)setMoreParticipantsString:(NSString *)_more {
-  ASSIGN(self->moreParticipantsString,_more);
-}
-- (NSString *)moreParticipantsString {
-  return self->moreParticipantsString;
-}
-
-- (void)setParticipantsSeparator:(NSString *)_sep {
-  ASSIGN(self->participantsSeparator,_sep);
-}
-- (NSString *)participantsSeparator {
-  return self->participantsSeparator;
-}
-
-- (void)setRelationDate:(NSCalendarDate *)_relation {
-  ASSIGN(self->relationDate,_relation);
-}
-- (NSCalendarDate *)relationDate {
-  return self->relationDate;
-}
-
-- (void)setShowFullNames:(BOOL)_flag {
-  self->showFullNames = _flag;
-}
-- (BOOL)showFullNames {
-  return self->showFullNames;
-}
-
-// easy switching
-- (void)switchToAMPMTimes:(BOOL)_showAMPM {
-  if (_showAMPM) {
-    [self setDateFormat:@"%I:%M %p"];
-    [self setOtherDayDateFormat:@"%I:%M %p(%m-%d)"];
-    [self setOtherYearDateFormat:@"%I:%M %p(%Y-%m-%d)"];
-  }
-  else {
-    [self setDateFormat:@"%H:%M"];
-    [self setOtherDayDateFormat:@"%H:%M(%m-%d)"];
-    [self setOtherYearDateFormat:@"%H:%M(%Y-%m-%d)"];
-  }
-}
-
-// formatting helpers
-
-- (NSString *)formatDate:(NSCalendarDate *)_date
-              withFormat:(NSString *)_format
-{
-  NSString *f;
-  NSCalendarDate *rel;
-
-  rel = self->relationDate;
-  
-  if (_format == nil) {
-    if (rel == nil) {
-      f = self->dateFormat;
-    }
-    else if ([_date isDateOnSameDay:rel]) {
-      f = self->dateFormat;
-    }
-    else if ([_date yearOfCommonEra] == [rel yearOfCommonEra]) {
-      f = self->otherDayDateFormat;
-    }
-    else {
-      f = self->otherYearDateFormat;
-    }
-  }
-  else {
-    f = _format;
-  }
-  return [_date descriptionWithCalendarFormat:f];
-}
-
-- (NSString *)formatStartDateFromApt:(id)_apt
-                          withFormat:(NSString *)_format
-{
-  return [self formatDate:[_apt valueForKey:@"startDate"]
-               withFormat:_format];
-}
-
-- (NSString *)formatEndDateFromApt:(id)_apt
-                        withFormat:(NSString *)_format
-{
-  return [self formatDate:[_apt valueForKey:@"endDate"]
-               withFormat:_format];
-}
-
-- (NSString *)stringForParticipant:(id)_part {
-  id label = nil;
-  
-  if ([[_part valueForKey:@"isTeam"] boolValue]) {
-    if ((label = [_part valueForKey:@"info"]) == nil)
-      label = [_part valueForKey:@"description"];
-  }
-  else if (self->showFullNames) {
-    label = [_part valueForKey:@"firstname"];
-    label = ([label length])
-      ? [label stringByAppendingFormat:@" %@", [_part valueForKey:@"name"]]
-      : [_part valueForKey:@"name"];
-  }
-  else if ([[_part valueForKey:@"isAccount"] boolValue]) {
-    label = [_part valueForKey:@"login"];
-  }
-  else {
-    if ((label = [_part valueForKey:@"name"]) == nil) {
-      if ((label = [_part valueForKey:@"info"]) == nil)
-        label = [_part valueForKey:@"description"];
-    }
-  }
-
-  if (![label isNotNull])
-    label = @"*";
-
-  return label;
-}
-
-- (NSString *)participantsForApt:(id)_apt
-                    withMaxCount:(NSString *)_cnt {
-  NSArray         *p;
-  int             max;
-  int             cnt;
-  NSMutableString *pString;
-
-  pString = [NSMutableString stringWithCapacity:255];
-
-  if (_cnt == nil) {
-    max = -1; // no limit
-  }
-  else {
-    max = [_cnt intValue];
-  }
-
-  p = [_apt valueForKey:@"participants"];
-
-  p = [p sortedArrayUsingKeyOrderArray:
-         [NSArray arrayWithObjects:
-                  [EOSortOrdering sortOrderingWithKey:@"isAccount"
-                                  selector:EOCompareAscending],
-                  [EOSortOrdering sortOrderingWithKey:@"login"
-                                  selector:EOCompareAscending],
-                  nil]];
-
-  max = ((max > [p count]) || (max == -1))
-    ? [p count]
-    : max;
-
-  for (cnt = 0; cnt < max; cnt++) {
-
-    if (cnt != 0)
-      [pString appendString:self->participantsSeparator];
-      
-    [pString appendString:
-             [self stringForParticipant:[p objectAtIndex:cnt]]];
-  }
-
-  if (max < [p count]) {
-    [pString appendString:self->moreParticipantsString];
-  }
-
-  return pString;
-}
-
-- (NSString *)titleForApt:(id)_apt withMaxLength:(NSString *)_length {
-  NSString    *t = nil;
-  int l;
-
-  l = (_length == nil)
-    ? -1
-    : [_length intValue];
-
-  t = [_apt valueForKey:@"title"];
-  if (!t) return @"*";
-
-  if (l > 1) {
-    if ([t length] > l) {
-      t = [t substringToIndex:(l - 2)];
-      t = [t stringByAppendingString:self->toLongString];
-    }
-  }
-  
-  if (l == 0)
-    t = @"*";
-  
-  return t;
-}
-
-- (NSString *)locationForApt:(id)_apt withMaxLength:(NSString *)_length {
-  NSString    *t = nil;
-  int l;
-
-  l = (_length == nil)
-    ? -1
-    : [_length intValue];
-
-  t = [_apt valueForKey:@"location"];
-  if (![t isNotNull] ||
-      [t length] == 0 ||
-      [t isEqualToString:@" "])
-    return @"";
-  
-  if (l > 1) {
-    if ([t length] > l) {
-      t = [t substringToIndex:(l - 2)];
-      t = [t stringByAppendingString:self->toLongString];
-    }
-  }
-  
-  if (l == 0)
-    t = @"";
-  
-  return t;
-}
-
-- (NSString *)resourcesForApt:(id)_apt withMaxLength:(NSString *)_length {
-  NSString    *t = nil;
-  int l;
-
-  l = (_length == nil)
-    ? -1
-    : [_length intValue];
-
-  t = [_apt valueForKey:@"resourceNames"];
-  if (![t isNotNull]  ||
-      [t length] == 0 ||
-      [t isEqualToString:@" "])
-    return @"";
-
-  if (l > 1) {
-    if ([t length] > l) {
-      t = [t substringToIndex:(l - 2)];
-      t = [t stringByAppendingString:self->toLongString];
-    }
-  }
-  
-  if (l == 0)
-    t = @"";
-  
-  return t;
-}
-
-// NSFormatter stuff
-
-- (NSString *)stringForObjectValue:(id)_obj {
-  NSMutableString *newString;
-  int             cnt;
-  int             length;
-  BOOL            replaceMode = NO;
-  NSString        *helper = nil;
-  NSCharacterSet  *digits;
-
-  newString = [NSMutableString stringWithCapacity:255];
-  length    = [self->formatString length];
-  digits    = [NSCharacterSet decimalDigitCharacterSet];
-
-  //  NSLog(@"Formatting with format: %@", self->formatString);
-
-  for (cnt = 0; cnt < length; cnt++) {
-    unichar c;
-    c = [self->formatString characterAtIndex:cnt];
-    //    NSLog(@"Character is: %c mode is: %@", c,
-    //          [NSNumber numberWithBool:replaceMode]);
-    if (replaceMode) {
-      if (c == 'S') {
-        [newString appendString:
-                   [self formatStartDateFromApt:_obj withFormat:helper]];
-        helper = nil;
-        replaceMode = NO;
-      }
-      else if (c == 'E') {
-        [newString appendString:
-                   [self formatEndDateFromApt:_obj withFormat:helper]];
-        helper = nil;
-        replaceMode = NO;
-      }
-      else if (c == 'P') {
-        [newString appendString:
-                   [self participantsForApt:_obj withMaxCount:helper]];
-        helper = nil;
-        replaceMode = NO;
-      }
-      else if (c == 'T') {
-        [newString appendString:
-                   [self titleForApt:_obj withMaxLength:helper]];
-        helper = nil;
-        replaceMode = NO;
-      }
-      else if (c == 'L') {
-        NSString *l;
-
-        l = [self locationForApt:_obj withMaxLength:helper];
-
-        if ([l length] > 0)
-          [newString appendString:l];
-        helper = nil;
-        replaceMode = NO;
-      }
-      else if (c == 'R') {
-        NSString *r;
-
-        r = [self resourcesForApt:_obj withMaxLength:helper];
-
-        if ([r length] > 0)
-          [newString appendString:r];
-        helper = nil;
-        replaceMode = NO;
-      }
-      else if (c == '(') {
-        int     end;
-        NSRange r = NSMakeRange(cnt,length-cnt);
-        
-        r = [self->formatString rangeOfString:@")"
-                 options:0 range:r];
-        
-        end = r.location - 1;
-        r = NSMakeRange(cnt+1, end-cnt-1);
-        
-        helper = [self->formatString substringWithRange:r];
-        cnt = end + 1;
-      }
-      else if ([digits characterIsMember:c]) {
-        helper = (helper == nil)
-          ? [NSString stringWithFormat:@"%c",c]
-          : [NSString stringWithFormat:@"%@%c", helper, c];
-      }
-      else {
-        NSLog(@"UNKNOWN FORMAT CHARACTER '%c'!!",c);
-        replaceMode = NO;
-        helper = nil;
-      }
-    } else {
-      if (c == '%') {
-        replaceMode = YES;
-      }
-      else {
-        [newString appendFormat:@"%c", c];
-      }
-    }
-  }
-  
-  return newString;
-}
-
-@end
index 44f9b9b1dc44569921f4b60c5bc000262456c900..9346d7742c4d61d7a8ff56e18388a49c91f18487 100644 (file)
   return [self redirectToLocation:url];
 }
 
-- (id)acceptAction {
-  if ([self appointment] == nil) {
-    return [NSException exceptionWithHTTPStatus:404
-                        reason:@"could not locate appointment"];
-  }
-  return self;
-}
-
-- (id)rejectAction {
-  if ([self appointment] == nil) {
-    return [NSException exceptionWithHTTPStatus:404
-                                         reason:@"could not locate appointment"];
-  }
-  return self;
-}
-
 @end /* UIxAppointmentView */
index 1b15f9ef1d4c08a8359bbeec1c4689998777ab60..3cff5577ffa6d47a2c591d734747f29b9d840c8f 100644 (file)
               <table width="100%" border="0" cellpadding="4" cellspacing="0">
               <tr valign="top">
                 <td align="left" bgcolor="#E8E8E0" class="aptview_title">
-                    <var:string label:value="Name" />
+                  <var:string label:value="Name" />
                 </td>
                 <td align="left" bgcolor="#E8E8E0" class="aptview_title">
-                    <var:string label:value="Email" />
+                  <var:string label:value="Email" />
+                </td>
+                <td align="left" bgcolor="#E8E8E0" class="aptview_title">
+                  <var:string label:value="Status" />
                 </td>
               </tr>
               <var:foreach list="appointment.participants"
                            item="attendee"
               >
-              <tr valign="top">
-                <td align="left" bgcolor="#FFFFF0" class="aptview_text">
+                <tr valign="top">
+                  <td align="left" bgcolor="#FFFFF0" class="aptview_text">
                     <var:string value="attendee.cnForDisplay" />
-                </td>
-                <td align="left" bgcolor="#FFFFF0" class="aptview_text">
+                  </td>
+                  <td align="left" bgcolor="#FFFFF0" class="aptview_text">
                     <a var:href="attendee.email"
                     ><var:string value="attendee.rfc822Email" /></a>
-                </td>
-              </tr>
+                  </td>
+                  <td align="left" bgcolor="#FFFFF0" class="aptview_text">
+                    <var:component className="UIxCalParticipationStatusView"
+                                   partStat="attendee.participationStatus"
+                    />
+                  </td>
+                </tr>
               </var:foreach>
               </table>
             </uix:tab>
diff --git a/SOGo/UI/Scheduler/UIxCalParticipationStatusView.m b/SOGo/UI/Scheduler/UIxCalParticipationStatusView.m
new file mode 100644 (file)
index 0000000..a08adac
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+  Copyright (C) 2000-2004 SKYRIX Software AG
+
+  This file is part of OGo
+
+  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.
+*/
+// $Id$
+
+
+#include <NGObjWeb/NGObjWeb.h>
+
+
+@interface UIxCalParticipationStatusView : WOComponent
+{
+    int partStat;
+}
+
+- (NSString *)participationStatus;
+
+@end
+
+#include <NGiCal/NGiCal.h> /* for iCalPersonPartStat */
+#include "common.h"
+
+@implementation UIxCalParticipationStatusView
+
+- (void)setPartStat:(id)_partStat {
+    self->partStat = [_partStat intValue];
+}
+
+- (NSString *)participationStatus {
+    switch (self->partStat) {
+        case iCalPersonPartStatNeedsAction:
+            return @"NEEDS-ACTION";
+        case iCalPersonPartStatAccepted:
+            return @"ACCEPTED";
+        case iCalPersonPartStatDeclined:
+            return @"DECLINED";
+        case iCalPersonPartStatTentative:
+            return @"TENTATIVE";
+        case iCalPersonPartStatDelegated:
+            return @"DELEGATED";
+    }
+    return @"OTHER";
+}
+
+- (NSString *)participationStatusLabel {
+    return [NSString stringWithFormat:@"partStat_%@",
+                                        [self participationStatus]];
+}
+
+@end
diff --git a/SOGo/UI/Scheduler/UIxCalParticipationStatusView.wox b/SOGo/UI/Scheduler/UIxCalParticipationStatusView.wox
new file mode 100644 (file)
index 0000000..c4d5d41
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version='1.0' standalone='yes'?>
+
+<var:string xmlns="http://www.w3.org/1999/xhtml"
+            xmlns:var="http://www.skyrix.com/od/binding"
+            xmlns:const="http://www.skyrix.com/od/constant"
+            xmlns:label="OGo:label"
+            label:value="$participationStatusLabel"
+/>
index 2736ba93b8da47eabc6d27f8e1ba07b87177c7d9..06cd0b6d5633a3965b1d1e9be3999152f9d00cb1 100644 (file)
@@ -28,6 +28,9 @@
   NSMutableArray *userApts;
   NSMutableArray *foreignApts;
   id             item;
+  NSArray        *partNames;
+  NSArray        *partStates;
+  unsigned       participantIndex;
 }
 
 - (NSCalendarDate *)startDate;
 
 - (NSString *)appointmentBaseURL;
 
+- (unsigned)participantsCount;
+- (unsigned)maxRenderedParticipantsCount;
+- (unsigned)renderedParticipantsCount;
+- (unsigned)truncatedParticipantsCount;
+- (BOOL)didTruncateParticipants;
+
 @end
 
 #include <NGObjWeb/SoComponent.h>
@@ -56,6 +65,8 @@
 - (void)dealloc {
   [self->userApts    release];
   [self->foreignApts release];
+  [self->partNames   release];
+  [self->partStates  release];
   [self->item        release];
   [super dealloc];
 }
 /* accessors */
 
 - (void)setItem:(id)_item {
+  NSString *ps;
+
   ASSIGN(self->item, _item);
+
+  [self->partNames release];
+  [self->partStates release];
+  ps               = [self->item valueForKey:@"participants"];
+  self->partNames  = [[ps componentsSeparatedByString:@"\n"] retain];
+  ps               = [self->item valueForKey:@"partstates"];
+  self->partStates = [[ps componentsSeparatedByString:@"\n"] retain];
+  NSLog(@"new item:%@", self->item);
 }
 - (id)item {
   return self->item;
 }
 
+- (void)setParticipantIndex:(unsigned)_participantIndex {
+  NSLog(@"_participantIndex:%d", _participantIndex);
+  self->participantIndex = _participantIndex;
+}
+- (unsigned)participantIndex {
+  return self->participantIndex;
+}
+
 - (BOOL)hasUserAppointments {
   return [[self userAppointments] count] > 0;
 }
           [self hasForeignAppointments]) ? YES : NO;
 }
 
-- (NSString *)participants {
-  NSString *s;
+- (unsigned)participantsCount {
+  return [self->partNames count];
+}
+
+- (NSString *)participant {
+  [self logWithFormat:@"participant(%d):%@",
+    self->participantIndex,
+    [self->partNames objectAtIndex:self->participantIndex]];
+  return [self->partNames objectAtIndex:self->participantIndex];
+}
+
+- (NSString *)participationStatus {
+  [self logWithFormat:@"state(%d):%@",
+    self->participantIndex,
+    [self->partStates objectAtIndex:self->participantIndex]];
+  return [self->partStates objectAtIndex:self->participantIndex];
+}
+
+- (unsigned)maxRenderedParticipantsCount {
+  return 2;
+}
+
+// TODO: find the bug in WORepetition and get rid of this!
+- (NSArray *)renderedParticipants {
+  NSRange r;
   
-  s = [self->item valueForKey:@"participants"];
-  if (!s)
-    return @"";
-  if ([s length] > 100)
-    s = [NSString stringWithFormat:@"%@...", [s substringToIndex:100]];
-  return s;
+  r = NSMakeRange(0, [self renderedParticipantsCount]);
+  return [self->partNames subarrayWithRange:r];
+}
+- (void)setFoo:(id)_foo {
+}
+
+- (unsigned)renderedParticipantsCount {
+  if ([self didTruncateParticipants])
+    return [self maxRenderedParticipantsCount];
+  return [self participantsCount];
+}
+
+- (unsigned)truncatedParticipantsCount {
+  return [self participantsCount] - [self renderedParticipantsCount];
+}
+
+- (BOOL)didTruncateParticipants {
+  return [self participantsCount] > [self maxRenderedParticipantsCount] ? YES
+                                                                        : NO;
 }
 
 
 - (NSString *)acceptAppointmentURL {
   return [[self appointmentBaseURL] stringByAppendingPathComponent:@"accept"];
 }
-- (NSString *)rejectAppointmentURL {
-  return [[self appointmentBaseURL] stringByAppendingPathComponent:@"reject"];
+- (NSString *)declineAppointmentURL {
+  return [[self appointmentBaseURL] stringByAppendingPathComponent:@"decline"];
 }
 
 
index 3acd437f3adcb703ae8b4c0c9e311a66666e40d7..57d93c6ccdcfa517d97b1bd00f6db7fa10e4bafd 100644 (file)
@@ -47,7 +47,9 @@
                                currentDate="selectedDate"
                 >
                   <var:if condition="hasAnyAppointments" const:negate="YES">
-                    <var:string label:value="No appointments found" />
+                    <var:string label:value="No appointments found"
+                                const:style="schedoverview"
+                    />
                   </var:if>
                   <var:if condition="hasAnyAppointments">
                     <table border="0"
                                /></a>
                             </td>
                             <td class="schedoverview" colspan="2">
-                              <var:string value="participants"
-                                          const:escapeHTML="YES"
-                                          const:insertBR="YES"
-                              />
+                              <table border="0"
+                                     width="100%"
+                                     cellpadding="0"
+                                     cellspacing="0"
+                                     class="schedoverview"
+                              >
+                                <var:foreach list="renderedParticipants"
+                                             index="participantIndex"
+                                             item="foo"
+                                >
+                                  <tr>
+                                    <td class="schedoverview">
+                                      <var:string value="participant" />
+                                    </td>
+                                    <td class="schedoverview">
+                                      <var:component className="UIxCalParticipationStatusView"
+                                                     partStat="participationStatus"
+                                      />
+                                    </td>
+                                  </tr>
+                                </var:foreach>
+                                <var:if condition="didTruncateParticipants">
+                                  <tr>
+                                    <td colspan="2" class="schedoverview">
+                                      <a var:href="appointmentViewURL"
+                                         class="schedoverview"
+                                      ><var:string value="truncatedParticipantsCount" />
+                                      <var:string label:value="more participants" />...
+                                      </a>
+                                    </td>
+                                  </tr>
+                                </var:if>
+                              </table>
                             </td>
                           </tr>
                         </var:foreach>
                                /></a>
                             </td>
                             <td class="schedoverview">
-                              <var:string value="participants"
-                                          const:escapeHTML="YES"
-                                          const:insertBR="YES"
-                              />
+                              <table border="0"
+                                     width="100%"
+                                     cellpadding="0"
+                                     cellspacing="2"
+                                     class="schedoverview"
+                              >
+                                <var:foreach list="renderedParticipants"
+                                             index="participantIndex"
+                                             item="foo"
+                                >
+                                  <tr>
+                                    <td class="schedoverview">
+                                      <var:string value="participant" />
+                                    </td>
+                                    <td class="schedoverview">
+                                      <var:component className="UIxCalParticipationStatusView"
+                                                     partStat="participationStatus"
+                                      />
+                                    </td>
+                                  </tr>
+                                </var:foreach>
+                                <var:if condition="didTruncateParticipants">
+                                  <tr>
+                                    <td colspan="2" class="schedoverview">
+                                      <a var:href="appointmentViewURL"
+                                         class="schedoverview"
+                                      ><var:string value="truncatedParticipantsCount" />
+                                      <var:string label:value="more participants" />...
+                                      </a>
+                                    </td>
+                                  </tr>
+                                </var:if>
+                              </table>
                             </td>
                             <td class="schedoverview">
                               <a var:href="acceptAppointmentURL"
                                  class="schedoverview"
                               ><var:string label:value="accept" /></a><br />
-                              <a var:href="rejectAppointmentURL"
+                              <a var:href="declineAppointmentURL"
                                  class="schedoverview"
-                              ><var:string label:value="reject" /></a>
+                              ><var:string label:value="decline" /></a>
                             </td>
                           </tr>
                         </var:foreach>
                       </var:if>
                     </table>
                   </var:if>
-                  <p>      
-                    workflow<br />
-                    ========<br />
-                    
-                    in fact, the workflow we wish to implement is :
-                    person A sets a meeting with B and C
-                    when he sets it, he clicks on a button : either "propose" or
-                    "propose and mail" (obvious)
-                    In both case, when B and C logs into SOGo, they see, in their
-                    'news page', that a new meeting has beeing proposed
-                    then by clicking on it, they can accept it
-                    on the news, you have to show : meetings proposed to the person
-                    logging in, meetings proposed BY the person logging in,
-                    and their different acceptance
-                    
-                    if you reject the meeting, it still appears in the news page
-                    as refused
-                    
-                    We have still two issues : ergonomic and functionnal
-                    
-                    The ergonomic one : I propose two sections in the news page,
-                    with each being a table, containing, each line, an apt,
-                    with title, day, hour, participants (truncated), the line
-                    being green if it has been accepted by all, red if rejected
-                    by someone
-                    grey if in another state
-                    
-                    the functionnal : a meeting that is still not accepted by
-                    everyone must appear in each participant's view, and be
-                    counted in the conflict manager, or not ?
-                    it's an open point
-                  </p>
+                  <var:if condition="isUIxDebugEnabled">
+                    <p class="schedoverview">      
+                      workflow<br />
+                      ========<br />
+                      
+                      in fact, the workflow we wish to implement is :
+                      person A sets a meeting with B and C
+                      when he sets it, he clicks on a button : either "propose" or
+                      "propose and mail" (obvious)
+                      In both case, when B and C logs into SOGo, they see, in their
+                      'news page', that a new meeting has beeing proposed
+                      then by clicking on it, they can accept it
+                      on the news, you have to show : meetings proposed to the person
+                      logging in, meetings proposed BY the person logging in,
+                      and their different acceptance
+                      
+                      if you reject the meeting, it still appears in the news page
+                      as refused
+                      
+                      We have still two issues : ergonomic and functionnal
+                      
+                      The ergonomic one : I propose two sections in the news page,
+                      with each being a table, containing, each line, an apt,
+                      with title, day, hour, participants (truncated), the line
+                      being green if it has been accepted by all, red if rejected
+                      by someone
+                      grey if in another state
+                      
+                      the functionnal : a meeting that is still not accepted by
+                      everyone must appear in each participant's view, and be
+                      counted in the conflict manager, or not ?
+                      it's an open point
+                    </p>
+                  </var:if>
                 </var:component>
               </td>
             </tr>
index 899fd136720a7bd2f47bd4172a36beb616eb4acc..c1e7d0d4b694000ead26ab673c65e02da63482b4 100644 (file)
@@ -2,7 +2,6 @@
 
 #include "UIxCalView.h"
 #include "common.h"
-#include "UIxAppointmentFormatter.h"
 #include <OGoContentStore/OCSFolder.h>
 #include "SoObjects/Appointments/SOGoAppointmentFolder.h"
 #include <NGObjWeb/SoUser.h>
@@ -351,8 +350,9 @@ static BOOL shouldDisplayWeekend = NO;
       continue;
     }
     
-    res = [[self clientObject] fetchCoreInfosFromFolder:folder 
-                              from:[self startDate] to:[self endDate]];
+    res = [[self clientObject] fetchOverviewInfosFromFolder:folder 
+                                                from:[self startDate]
+                               to:[self endDate]];
     if (res == nil) {
       [self errorWithFormat:@"fetch failed for user: %@", uid];
       continue;
@@ -388,7 +388,8 @@ static BOOL shouldDisplayWeekend = NO;
   
   aptFolder = [self clientObject];
   self->appointments =
-    [[aptFolder fetchCoreInfosFrom:[self startDate] to:[self endDate]] retain];
+    [[aptFolder fetchOverviewInfosFrom:[self startDate]
+                to:[self endDate]] retain];
   
   uids = [[[[self context] request] formValueForKey:@"uids"] stringValue];
   uids = [uids length] > 0 ? [uids componentsSeparatedByString:@","] : nil;
index 4405f93a2c7b26e6408042428979ba76f8e9181c..07748cc2bdc50162ac78f504f64bf5752f796f4b 100644 (file)
@@ -1,6 +1,6 @@
 # $Id$
 
-SUBMINOR_VERSION:=103
+SUBMINOR_VERSION:=104
 
 # v0.9.101 requires NGiCal       v4.5.36
 # v0.9.100 requires SOGoUI       v0.9.21
index c74966145f996b08455f39f9f9d450a8634fafe2..62fd572e7d058e4bfc6e0187953f33bef7aeee58 100644 (file)
           pageName    = "UIxAppointmentView"; 
           actionName  = "delete";
         };
-        accept = { 
+        edit = { 
           protectedBy = "View";
-          pageName    = "UIxAppointmentView"; 
-          actionName  = "accept";
+          pageName    = "UIxAppointmentEditor"; 
         };
-        reject = { 
+        save = { 
           protectedBy = "View";
-          pageName    = "UIxAppointmentView"; 
-          actionName  = "reject";
+          pageName    = "UIxAppointmentEditor"; 
+          actionName  = "save";
         };
-        edit = { 
+        accept = { 
           protectedBy = "View";
           pageName    = "UIxAppointmentEditor"; 
+          actionName  = "accept";
         };
-        save = { 
+        decline = { 
           protectedBy = "View";
           pageName    = "UIxAppointmentEditor"; 
-          actionName  = "save";
+          actionName  = "decline";
         };
         test = { 
           protectedBy = "View";
index fa432734044b43bc1c37dd06b8d51292aae70966..24f8b6b2429401c813dde47ed5ed745acc7ee6f4 100644 (file)
@@ -1,3 +1,12 @@
+2004-12-17  Marcus Mueller  <znek@mulle-kybernetik.com>
+
+       * v0.9.32
+
+       * SOGoAppointmentICalRenderer.m: add correct participant state
+
+       * SOGoAppointment.[hm]: find participants with specific email
+         address.
+
 2004-12-13  Marcus Mueller  <znek@mulle-kybernetik.com>
 
        * SOGoAppointment.m: removed UIx_Privates declaration (no longer
index f358d921ddb5c24b2c0ceedd711676d00886b271..774dd757b2ffb15b89bce7bfdc23a1865c78ed67 100644 (file)
 
 - (BOOL)isOrganizer:(id)_email;
 - (BOOL)isParticipant:(id)_email;
-  
+
+/* searching */
+
+- (iCalPerson *)findParticipantWithEmail:(id)_email;
+
 @end
 
 #endif /* __SOGoAppointment_H_ */
index 06c7c116d32a26b1264b86f9a6725f6ead167ca1..802e89aa3100e9750b25498b303eeff2ff3fa2d7 100644 (file)
@@ -373,6 +373,23 @@ static NGLogger                  *logger = nil;
   return [partEmails containsObject:_email];
 }
 
+- (iCalPerson *)findParticipantWithEmail:(id)_email {
+  NSArray  *ps;
+  unsigned i, count;
+  
+  ps    = [self participants];
+  count = [ps count];
+  
+  for (i = 0; i < count; i++) {
+    iCalPerson *p;
+    
+    p = [ps objectAtIndex:i];
+    if ([[p rfc822Email] isEqualToString:_email])
+      return p;
+  }
+  return nil; /* not found */
+}
+
 /* description */
 
 - (void)appendAttributesToDescription:(NSMutableString *)_ms {
index 32e0739d690c1e5d8a557ee9bafacaf65db343fb..ecba50dadc7e2801ef2c8a3d2bfeede9e7d8f2b4 100644 (file)
@@ -103,8 +103,16 @@ static unsigned DefaultICalStringCapacity = 1024;
       [s appendString:@";"];
     }
     
+    if ((x = [p partStat])) {
+      if ([p participationStatus] != iCalPersonPartStatNeedsAction) {
+        [s appendString:@"PARTSTAT="];
+        [s appendString:[x iCalSafeString]];
+        [s appendString:@";"];
+      }
+    }
+
     [s appendString:@"CN=\""];
-    if ((x = [p cn])) {
+    if ((x = [p cnWithoutQuotes])) {
       [s appendString:[x iCalDQUOTESafeString]];
     }
     [s appendString:@"\""];
index 6a99300f7c03a06d68864e43a507bbf8fc64e4c1..2ab989269ad87f26a552b06917b1417ecb469116 100644 (file)
@@ -1,7 +1,8 @@
 # Version file
 
-SUBMINOR_VERSION:=31
+SUBMINOR_VERSION:=32
 
+# v0.9.32 requires NGiCal        v4.5.37
 # v0.9.31 requires NGiCal        v4.5.36
 # v0.9.26 requires NGExtensions  v4.5.136
 # v0.9.23 requires NGiCal        v4.3.32