]> err.no Git - scalable-opengroupware.org/commitdiff
git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1031 d1b88da0-ebda-0310...
authorwolfgang <wolfgang@d1b88da0-ebda-0310-925b-ed51d893ca5b>
Wed, 7 Mar 2007 22:52:32 +0000 (22:52 +0000)
committerwolfgang <wolfgang@d1b88da0-ebda-0310-925b-ed51d893ca5b>
Wed, 7 Mar 2007 22:52:32 +0000 (22:52 +0000)
29 files changed:
ChangeLog
Main/SOGo.m
OGoContentStore/OCSiCalFieldExtractor.m
OGoContentStore/appointment.ocs
OGoContentStore/sql/appointment-create.psql
OGoContentStore/sql/generate-folderinfo-sql-for-users.sh
SOPE/NGCards/CardElement.m
SOPE/NGCards/CardGroup.m
SOPE/NGCards/CardVersitRenderer.m
SOPE/NGCards/ChangeLog
SOPE/NGCards/NSString+NGCards.m
SOPE/NGCards/iCalEntityObject.h
SOPE/NGCards/iCalEntityObject.m
SoObjects/Appointments/SOGoAppointmentFolder.m
SoObjects/Appointments/SOGoCalendarComponent.h
SoObjects/Appointments/SOGoCalendarComponent.m
SoObjects/Appointments/product.plist
SoObjects/SOGo/SOGoAuthenticator.h
SoObjects/SOGo/SOGoAuthenticator.m
UI/MailerUI/UIxMailReplyAction.m
UI/Scheduler/UIxCalInlineAptView.m
UI/Scheduler/UIxCalView.m
UI/Scheduler/UIxComponent+Agenor.h
UI/Scheduler/UIxComponent+Agenor.m
UI/Templates/SchedulerUI/UIxCalInlineAptView.wox
UI/WebServerResources/SchedulerUI.js
UI/WebServerResources/add-user-addressbook.png [new file with mode: 0644]
UI/WebServerResources/alarm.png [new file with mode: 0644]
UI/WebServerResources/repeat-16.png [new file with mode: 0644]

index f96850412459ff9122254d734d95a7e3974f3b95..331f0414f4f51be290ca4e7befb31fe39c99d44e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,60 @@
+2007-03-07  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * SoObjects/SOGo/SOGoAuthenticator.m ([SOGoAuthenticator
+       -userInContext:]): returns "SOGoUser".
+
+       * SoObjects/Appointments/SOGoCalendarComponent.m
+       ([SOGoCalendarComponent -contentAsString]): overriden method that
+       takes the privacy into account and discard the relevant fields if
+       needed by generating a new content string and caching it.
+       ([SOGoCalendarComponent
+       -saveContentString:contentStringbaseVersion:baseVersion]): if the
+       new method above has cached a content string, release it and set
+       it to nil so that it will have to be regenerated in the case it is
+       requested further.
+       ([SOGoCalendarComponent -_filterPrivateComponent:component]):
+       discard the fields that have to be hidden when the card is
+       private.
+
+       * SoObjects/Appointments/SOGoAppointmentFolder.m
+       ([SOGoAppointmentFolder
+       -appendObject:objectwithBaseURL:baseURLtoREPORTResponse:r]): make
+       sure the cards are now handled as instances of
+       SOGoCalendarComponent instead of SOGoContentObject so that their
+       content string is taking the privacy classifiction into account.
+       ([SOGoAppointmentFolder -_privacySqlString]): new method that
+       generates a query to determine what information can be given and
+       if the card itself has to be shown.
+
+       * UI/Scheduler/UIxComponent+Agenor.m ([UIxComponent
+       -getICalPersonsFromValue:selectorValue]): removed useless
+       "isAccessRestricted" method.
+
+       * UI/Scheduler/UIxCalInlineAptView.m ([UIxCalInlineAptView
+       -setStyle:_style]): test whether the values of orgmail and
+       partmails are null before manipulating them, otherwise SOGo sends
+       a "rangeOfString:" message to an NSNull, which makes it crashes.
+
+       * OGoContentStore/OCSiCalFieldExtractor.m ([OCSiCalFieldExtractor
+       -extractQuickFieldsFromEvent:_event]): we now use the new
+       "symbolicAccessClass" method from iCalEntity to determine the
+       value of the "classifiction" field.
+       ([OCSiCalFieldExtractor -extractQuickFieldsFromTodo:_task]): same
+       as above.
+
+2007-03-05  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * SoObjects/Appointments/SOGoAppointmentFolder.m
+       ([SOGoAppointmentFolder
+       -fetchCoreInfosFrom:_startDateto:_endDatecomponent:_component]):
+       see below, the query is adapted consequently.
+
+       * OGoContentStore/OCSiCalFieldExtractor.m ([OCSiCalFieldExtractor
+       -extractQuickFieldsFromTodo:_task]): the field "ispublic" was
+       renamed to "classification" and can any integer as value.
+       ([OCSiCalFieldExtractor -extractQuickFieldsFromEvent:_event]):
+       idem.
+
 2007-02-26  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
 
        * UI/MailPartViewers/UIxMailPartHTMLViewer.m
index 0f10c9846d2d6dc50f7c83eac127d1e4d687b28c..a427bd783569a8db60e8c7aefc5b994e88741c4f 100644 (file)
 
 #include <NGObjWeb/SoApplication.h>
 
+// @interface classtree : NSObject
+// {
+//   Class topClass;
+//   int indentLevel;
+// }
+
+// - (id) initWithTopClass: (Class) newTopClass;
+// - (void) dumpSiblings: (Class) node;
+
+// @end
+
+// @implementation classtree
+
+// + (id) newWithTopClass: (Class) newTopClass
+// {
+//   id newTree;
+
+//   newTree = [[self alloc] initWithTopClass: newTopClass];
+//   [newTree autorelease];
+
+//   return newTree;
+// }
+
+// - (id) initWithTopClass: (Class) newTopClass
+// {
+//   if ((self = [self init]))
+//     topClass = newTopClass;
+
+//   return self;
+// }
+
+// #define indentGap 2
+
+// - (NSString *) indentSpaces
+// {
+//   char *spaceString;
+
+//   spaceString = malloc(sizeof (char *) * indentGap * indentLevel + 1);
+//   *(spaceString + indentGap * indentLevel) = 0;
+//   memset (spaceString, ' ', indentGap * indentLevel);
+
+//   return [[NSString alloc] initWithCStringNoCopy: spaceString
+//                            length: indentGap * indentLevel
+//                            freeWhenDone: YES];
+// }
+
+// - (void) dumpNode: (Class) node
+// {
+//   Class currentSubclass;
+//   unsigned int count;
+
+//   count = 0;
+//   currentSubclass = node->subclass_list;
+//   if (currentSubclass)
+//     {
+//       NSLog(@"%@%@:",
+//             [[self indentSpaces] autorelease], NSStringFromClass(node));
+//       indentLevel++;
+//       [self dumpSiblings: currentSubclass];
+//       indentLevel--;
+//     }
+//   else
+//     NSLog(@"%@%@", [self indentSpaces], NSStringFromClass(node));
+// }
+
+// - (void) dumpSiblings: (Class) node
+// {
+//   Class currentNode;
+
+//   currentNode = node;
+//   while (currentNode && currentNode->instance_size)
+//     {
+//       [self dumpNode: currentNode];
+//       currentNode = currentNode->sibling_class;
+//     }
+// }
+
+// - (void) dumpTree
+// {
+//   indentLevel = 0;
+
+//   [self dumpSiblings: topClass];
+// }
+
+// @end
+
 @interface SOGo : SoApplication
 {
     NSMutableDictionary *localeLUT;
@@ -189,6 +275,14 @@ static BOOL doCrashOnSessionCreate = NO;
 
 /* runtime maintenance */
 
+// - (void) _dumpClassAllocation
+// {
+//   classtree *ct;
+
+//   ct = [classtree newWithTopClass: [NSObject class]];
+//   [ct dumpTree];
+// }
+
 - (void)checkIfDaemonHasToBeShutdown {
   unsigned int limit, vmem;
   
@@ -202,6 +296,7 @@ static BOOL doCrashOnSessionCreate = NO;
           @"terminating app, vMem size limit (%d MB) has been reached"
           @" (currently %d MB)",
           limit, vmem];
+//     [self _dumpClassAllocation];
     [self terminate];
   }
 }
index 09cbe20efc10ac0c3b60f932b20677bcd7e1de84..264893c74e174c9681ed55c183b55dbb06c0c902 100644 (file)
@@ -66,12 +66,13 @@ static NSNumber                  *distantFutureNumber = nil;
   NSMutableDictionary *row;
   NSCalendarDate      *startDate, *endDate;
   NSArray             *attendees;
-  NSString            *uid, *title, *location, *status, *accessClass;
+  NSString            *uid, *title, *location, *status;
   NSNumber            *sequence;
   id                  organizer;
   id                  participants, partmails;
   NSMutableString     *partstates;
   unsigned            i, count;
+  iCalAccessClass accessClass;
 
   if (_event == nil)
     return nil;
@@ -84,7 +85,7 @@ static NSNumber                  *distantFutureNumber = nil;
   title        = [_event summary];
   location     = [_event location];
   sequence     = [_event sequence];
-  accessClass  = [[_event accessClass] uppercaseString];
+  accessClass  = [_event symbolicAccessClass];
   status       = [[_event status] uppercaseString];
 
   attendees    = [_event attendees];
@@ -117,9 +118,9 @@ static NSNumber                  *distantFutureNumber = nil;
   if ([location isNotNull]) [row setObject: location forKey:@"location"];
   if ([sequence isNotNull]) [row setObject: sequence forKey:@"sequence"];
 
-  if ([startDate isNotNull]) 
+  if ([startDate isNotNull])
     [row setObject: [self numberForDate: startDate] forKey:@"startdate"];
-  if ([endDate isNotNull]) 
+  if ([endDate isNotNull])
     [row setObject: [self numberForDate: endDate] forKey:@"enddate"];
   if ([_event isRecurrent]) {
     NSCalendarDate *date;
@@ -153,12 +154,8 @@ static NSNumber                  *distantFutureNumber = nil;
     [row setObject: [NSNumber numberWithInt:1] forKey: @"status"];
   }
 
-  if([accessClass isNotNull] && ![accessClass isEqualToString:@"PUBLIC"]) {
-    [row setObject:[NSNumber numberWithBool:NO] forKey:@"ispublic"];
-  }
-  else {
-    [row setObject:[NSNumber numberWithBool:YES] forKey:@"ispublic"];
-  }
+  [row setObject: [NSNumber numberWithUnsignedInt: accessClass]
+       forKey: @"classification"];
 
   organizer = [_event organizer];
   if (organizer) {
@@ -192,12 +189,13 @@ static NSNumber                  *distantFutureNumber = nil;
   NSMutableDictionary *row;
   NSCalendarDate      *startDate, *dueDate;
   NSArray             *attendees;
-  NSString            *uid, *title, *location, *status, *accessClass;
+  NSString            *uid, *title, *location, *status;
   NSNumber            *sequence;
   id                  organizer, date;
   id                  participants, partmails;
   NSMutableString     *partstates;
   unsigned            i, count, code;
+  iCalAccessClass accessClass;
 
   if (_task == nil)
     return nil;
@@ -210,7 +208,7 @@ static NSNumber                  *distantFutureNumber = nil;
   title        = [_task summary];
   location     = [_task location];
   sequence     = [_task sequence];
-  accessClass  = [[_task accessClass] uppercaseString];
+  accessClass  = [_task symbolicAccessClass];
   status       = [[_task status] uppercaseString];
 
   attendees    = [_task attendees];
@@ -271,12 +269,8 @@ static NSNumber                  *distantFutureNumber = nil;
     [row setObject:[NSNumber numberWithInt:1] forKey:@"status"];
   }
 
-  if([accessClass isNotNull] && ![accessClass isEqualToString:@"PUBLIC"]) {
-    [row setObject:[NSNumber numberWithBool:NO] forKey:@"ispublic"];
-  }
-  else {
-    [row setObject:[NSNumber numberWithBool:YES] forKey:@"ispublic"];
-  }
+  [row setObject: [NSNumber numberWithUnsignedInt: accessClass]
+       forKey: @"classification"];
 
   organizer = [_task organizer];
   if (organizer) {
index 8e014e4a798fd839d85c5d55a33b450dc11b4f03..966680e4f71fe6eea86fe40413393da1cf9ca8d8 100644 (file)
@@ -55,7 +55,7 @@
       allowsNull = YES;
     },
     {
-      columnName = ispublic;
+      columnName = classification;
       sqlType    = "INT";
       allowsNull = NO;
     },
index 94c370c6144dedcb00f539f69529c1b7fe5f84e0..8ec451606397571a2b3117465de99d31daff936b 100644 (file)
@@ -11,7 +11,7 @@ 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,
+  classification     INT             NOT NULL,
   status       INT             NOT NULL,
   isopaque     INT             NOT NULL,
   location     VARCHAR(256)    NULL,
index ed2e01833ec83a786c0d903e918e61d5185d1274..e8ba9c594bd80029b6385d64afeec14369badd10 100755 (executable)
@@ -82,7 +82,7 @@ CREATE TABLE SOGo_${USER_TABLE}_privcal_quick (
   participants VARCHAR(100000) NULL, -- the CNs of the participants
   isallday     INT             NULL,
   iscycle      INT             NULL,     -- client needs to fetch to resolve
-  ispublic     INT             NOT NULL,
+  classification INT             NOT NULL,
   status       INT             NOT NULL,
   priority     INT             NOT NULL, -- for marking high prio apts
   isopaque     INT             NULL,
index cf4c489ae1008aaa2c436c8345f82417fa32de95..7af7e19bd3fb8afc29a9fbbe45bcc404e1f043ca 100644 (file)
 
 - (NSString *) versitString
 {
-  CardVersitRenderer *renderer;
   NSString *string;
+  CardVersitRenderer *renderer;
 
   renderer = [CardVersitRenderer new];
   string = [renderer render: self];
index ae375d46b550eb568204f3119eeafde3cdfad7d4..be1c71e01da6e6641a879c1554d58acb1d883ae5 100644 (file)
@@ -112,13 +112,7 @@ static NGCardsSaxHandler *sax = nil;
 
 + (id) groupWithTag: (NSString *) aTag
 {
-  id newGroup;
-
-  newGroup = [self new];
-  [newGroup autorelease];
-  [newGroup setTag: aTag];
-
-  return newGroup;
+  return [self elementWithTag: aTag];
 }
 
 + (id) groupWithTag: (NSString *) aTag
@@ -126,9 +120,7 @@ static NGCardsSaxHandler *sax = nil;
 {
   id newGroup;
 
-  newGroup = [self new];
-  [newGroup autorelease];
-  [newGroup setTag: aTag];
+  newGroup = [self elementWithTag: aTag];
   [newGroup addChildren: someChildren];
 
   return newGroup;
index 0643bbdcea4f93f65f0a265eedcdbd3c2557e911..523fddde53cd25daa842dff8d750e9a62a6181f4 100644 (file)
@@ -61,7 +61,6 @@
   if (![anElement isVoid])
     {
       rendering = [NSMutableString new];
-      [rendering autorelease];
       if ([anElement group])
         [rendering appendFormat: @"%@.", [anElement group]];
       tag = [anElement tag];
@@ -94,6 +93,7 @@
         [rendering appendString: @"\r\n"];
 
       finalRendering = [rendering foldedForVersitCards];
+      [rendering release];
     }
   else
     finalRendering = @"";
index 6b01b6497673a4e879ba3e572e5a7f8f6fe82537..c8f0df0948f7d873fa861360675fc755145659e6 100644 (file)
@@ -1,3 +1,24 @@
+2007-03-07  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * iCalEntityObject.m ([iCalEntityObject -symbolicAccessClass]):
+       new method that parses the "CLASS" element of the card and returns
+       an enum value.
+
+       * NSString+NGCards.m ([NSString -foldedForVersitCards]):
+       simplified method by initializing and returning folderString
+       unconditionnally. If length < 76, the original string is appended
+       to it.
+
+       * CardGroup.m ([CardGroup +groupWithTag:aTag]): simply invoke
+       [self elementWithTag:].
+       ([CardGroup +groupWithTag:aTagchildren:someChildren]): same as
+       above.
+
+2007-03-05  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
+
+       * iCalEntityObject.h (enum): added an enum with iCalAccessPublic,
+       iCalAccessPrivate and iCalAccessConfidential values.
+
 2007-02-15  Wolfgang Sourdeau  <wsourdeau@inverse.ca>
 
        * CardGroup.m ([CardGroup -firstChildWithTag:aTag]): new method.
index eb0c4e421e446fc248f3a57efc8626fcb485538c..21cee5b57127d7ebc4e540dbb3d6868c5f66ea6b 100644 (file)
@@ -42,19 +42,18 @@ static NSString *commaSeparator = nil;
 
 - (NSString *) foldedForVersitCards
 {
-  NSString *newString;
   NSMutableString *foldedString;
   unsigned int length;
   NSRange subStringRange;
 
+  foldedString = [NSMutableString new];
+  [foldedString autorelease];
+
   length = [self length];
   if (length < 76)
-    newString = self;
+    [foldedString appendString: self];
   else
     {
-      foldedString = [NSMutableString new];
-      [foldedString autorelease];
-
       subStringRange = NSMakeRange (0, 75);
       [foldedString appendFormat: @"%@\r\n",
                     [self substringWithRange: subStringRange]];
@@ -68,11 +67,9 @@ static NSString *commaSeparator = nil;
       subStringRange.length = length - subStringRange.location;
       [foldedString appendFormat: @" %@",
                     [self substringWithRange: subStringRange]];
-
-      newString = foldedString;
     }
 
-  return newString;
+  return foldedString;
 }
 
 - (NSArray *) asCardAttributeValues
index 0f748939b648c776d2f6c6563d318856f64f94cc..954c8f6613628e32a013bb3a810397defbb74afe 100644 (file)
 @class iCalPerson;
 @class NSURL;
 
+typedef enum
+{
+  iCalAccessPublic = 0,
+  iCalAccessPrivate = 1,
+  iCalAccessConfidential = 2,
+} iCalAccessClass;
+
 @interface iCalEntityObject : CardGroup
 
 /* accessors */
@@ -53,6 +60,7 @@
 
 - (void) setAccessClass:(NSString *) _value;
 - (NSString *) accessClass;
+- (iCalAccessClass) symbolicAccessClass;
 - (BOOL) isPublic;
 
 - (void) setPriority: (NSString *) _value;
index d45de9d0b78a7554a0927c3eb99b5765963bb505..1239e23393d9278f5a9ddd7898119773a0ec3ae9 100644 (file)
   return [[self uniqueChildWithTag: @"class"] value: 0];
 }
 
+- (iCalAccessClass) symbolicAccessClass
+{
+  iCalAccessClass symbolicAccessClass;
+  NSString *accessClass;
+
+  accessClass = [[self accessClass] uppercaseString];
+  if ([accessClass isEqualToString: @"PRIVATE"])
+    symbolicAccessClass = iCalAccessPrivate;
+  else if ([accessClass isEqualToString: @"CONFIDENTIAL"])
+    symbolicAccessClass = iCalAccessConfidential;
+  else
+    symbolicAccessClass = iCalAccessPublic;
+
+  return symbolicAccessClass;
+}
+
 - (BOOL) isPublic
 {
-  return [[[self accessClass] uppercaseString] isEqualToString: @"PUBLIC"];
+  return ([self symbolicAccessClass] == iCalAccessPublic);
 }
 
 - (void) setPriority: (NSString *) _value
index 6772e5e940d9b9cee3e7430a3ee2a4f9af086c42..dc901a3a053f54889c8602ae7ac233d19ccb060e 100644 (file)
@@ -32,6 +32,7 @@
 #import <SOGo/AgenorUserManager.h>
 #import <SOGo/SOGoPermissions.h>
 #import <SOGo/NSString+Utilities.h>
+#import <SOGo/SOGoUser.h>
 
 #import "common.h"
 
@@ -135,13 +136,18 @@ static NSNumber   *sharedYes = nil;
           withBaseURL: (NSString *) baseURL
      toREPORTResponse: (WOResponse *) r
 {
-  SOGoContentObject *ocsObject;
+  SOGoCalendarComponent *component;
+  Class componentClass;
   NSString *c_name, *etagLine, *calString;
 
   c_name = [object objectForKey: @"c_name"];
 
-  ocsObject = [SOGoContentObject objectWithName: c_name
-                                 inContainer: self];
+  if ([[object objectForKey: @"component"] isEqualToString: @"vevent"])
+    componentClass = [SOGoAppointmentObject class];
+  else
+    componentClass = [SOGoTaskObject class];
+
+  component = [componentClass objectWithName: c_name inContainer: self];
 
   [r appendContentString: @"  <D:response>\r\n"];
   [r appendContentString: @"    <D:href>"];
@@ -154,13 +160,13 @@ static NSNumber   *sharedYes = nil;
   [r appendContentString: @"    <D:propstat>\r\n"];
   [r appendContentString: @"      <D:prop>\r\n"];
   etagLine = [NSString stringWithFormat: @"        <D:getetag>%@</D:getetag>\r\n",
-                       [ocsObject davEntityTag]];
+                       [component davEntityTag]];
   [r appendContentString: etagLine];
   [r appendContentString: @"      </D:prop>\r\n"];
   [r appendContentString: @"      <D:status>HTTP/1.1 200 OK</D:status>\r\n"];
   [r appendContentString: @"    </D:propstat>\r\n"];
   [r appendContentString: @"    <C:calendar-data>"];
-  calString = [[ocsObject contentAsString] stringByEscapingXMLString];
+  calString = [[component contentAsString] stringByEscapingXMLString];
   [r appendContentString: calString];
   [r appendContentString: @"</C:calendar-data>\r\n"];
   [r appendContentString: @"  </D:response>\r\n"];
@@ -658,10 +664,37 @@ static NSNumber   *sharedYes = nil;
   end = (unsigned int) [_endDate timeIntervalSince1970];
 
   return [NSString stringWithFormat:
-                     @" AND (startdate <= %d) AND (enddate >= %d)",
+                     @" AND (startdate <= %u) AND (enddate >= %u)",
                    end, start];
 }
 
+- (NSString *) _privacySqlString
+{
+  NSString *privacySqlString, *owner, *currentUser, *email;
+  WOContext *context;
+  SOGoUser *activeUser;
+
+  context = [[WOApplication application] context];
+  activeUser = [context activeUser];
+  currentUser = [activeUser login];
+  owner = [self ownerInContext: context];
+
+  if ([currentUser isEqualToString: owner])
+    privacySqlString = @"";
+  else
+    {
+      email = [activeUser email];
+      privacySqlString
+        = [NSString stringWithFormat:
+                      @"(classification != %d or (orgmail = '%@')"
+                      @" or ((partmails caseInsensitiveLike '%@%%'"
+                      @" or partmails caseInsensitiveLike '%%\\n%@%%')))",
+                    iCalAccessPrivate, email, email, email];
+    }
+
+  return privacySqlString;
+}
+
 - (NSArray *) fetchFields: (NSArray *) _fields
                fromFolder: (GCSFolder *) _folder
                      from: (NSCalendarDate *) _startDate
@@ -671,7 +704,7 @@ static NSNumber   *sharedYes = nil;
   EOQualifier *qualifier;
   NSMutableArray *fields, *ma = nil;
   NSArray *records;
-  NSString *sql, *dateSqlString, *componentSqlString; /* , *owner; */
+  NSString *sql, *dateSqlString, *componentSqlString, *privacySqlString; /* , *owner; */
   NGCalendarDateRange *r;
 
   if (_folder == nil) {
@@ -693,6 +726,7 @@ static NSNumber   *sharedYes = nil;
     }
 
   componentSqlString = [self _sqlStringForComponent: _component];
+  privacySqlString = [self _privacySqlString];
 
   /* prepare mandatory fields */
 
@@ -704,8 +738,8 @@ static NSNumber   *sharedYes = nil;
   if (logger)
     [self debugWithFormat:@"should fetch (%@=>%@) ...", _startDate, _endDate];
 
-  sql = [NSString stringWithFormat: @"(iscycle = 0)%@%@",
-                  dateSqlString, componentSqlString];
+  sql = [NSString stringWithFormat: @"(iscycle = 0)%@%@%@",
+                  dateSqlString, componentSqlString, privacySqlString];
 
   /* fetch non-recurrent apts first */
   qualifier = [EOQualifier qualifierWithQualifierFormat: sql];
@@ -722,8 +756,8 @@ static NSNumber   *sharedYes = nil;
     }
 
   /* fetch recurrent apts now */
-  sql = [NSString stringWithFormat: @"(iscycle = 1)%@%@",
-                  dateSqlString, componentSqlString];
+  sql = [NSString stringWithFormat: @"(iscycle = 1)%@%@%@",
+                  dateSqlString, componentSqlString, privacySqlString];
   qualifier = [EOQualifier qualifierWithQualifierFormat: sql];
 
   [fields addObject: @"cycleinfo"];
@@ -807,12 +841,13 @@ static NSNumber   *sharedYes = nil;
     infos = [[NSArray alloc] initWithObjects:
                                @"c_name", @"component",
                              @"title", @"location", @"orgmail",
-                             @"status", @"ispublic",
+                             @"status", @"classification",
                              @"isallday", @"isopaque",
                              @"participants", @"partmails",
                              @"partstates", @"sequence", @"priority", nil];
 
-  return [self fetchFields: infos from: _startDate to: _endDate component: _component];
+  return [self fetchFields: infos from: _startDate to: _endDate
+               component: _component];
 }
 
 - (void) deleteEntriesWithIds: (NSArray *) ids
index 50e069ee5334d20d52b0dfff7d63bfd6d2686062..589b7dbb682654c718739f1fd706153c8002e047 100644 (file)
@@ -34,6 +34,7 @@
 @interface SOGoCalendarComponent : SOGoContentObject
 {
   iCalCalendar *calendar;
+  NSString *calContent;
 }
 
 - (NSString *) componentTag;
index c5e6e31118720e64334ab9ec35790098673a16ca..c79091a723fe4cf4e920b061d1c7b9482c8ec50b 100644 (file)
@@ -68,6 +68,7 @@ static BOOL sendEMailNotifications = NO;
   if ((self = [super init]))
     {
       calendar = nil;
+      calContent = nil;
     }
 
   return self;
@@ -77,6 +78,8 @@ static BOOL sendEMailNotifications = NO;
 {
   if (calendar)
     [calendar release];
+  if (calContent)
+    [calContent release];
   [super dealloc];
 }
 
@@ -92,6 +95,69 @@ static BOOL sendEMailNotifications = NO;
   return nil;
 }
 
+- (void) _filterPrivateComponent: (iCalEntityObject *) component
+{
+  [component setSummary: @""];
+  [component setComment: @""];
+  [component setUserComment: @""];
+  [component setLocation: @""];
+  [component setCategories: @""];
+  [component setUrl: @""];
+  [component removeAllAttendees];
+  [component removeAllAlarms];
+}
+
+- (NSString *) contentAsString
+{
+  NSString *tmpContent, *email;
+  iCalCalendar *tmpCalendar;
+  iCalRepeatableEntityObject *tmpComponent;
+  WOContext *context;
+
+  if (!calContent)
+    {
+      tmpContent = [super contentAsString];
+      calContent = tmpContent;
+      if ([tmpContent length] > 0)
+        {
+          tmpCalendar = [iCalCalendar parseSingleFromSource: tmpContent];
+          tmpComponent = (iCalRepeatableEntityObject *) [tmpCalendar firstChildWithTag: [self componentTag]];
+          if (![tmpComponent isPublic])
+            {
+              context = [[WOApplication application] context];
+              email = [[context activeUser] email];
+              if (!([tmpComponent isOrganizer: email]
+                    || [tmpComponent isParticipant: email]))
+                {
+                  //             content = tmpContent;
+                  [self _filterPrivateComponent: tmpComponent];
+                  calContent = [tmpCalendar versitString];
+                }
+            }
+        }
+
+      [calContent retain];
+    }
+
+  return calContent;
+}
+
+- (NSException *) saveContentString: (NSString *) contentString
+                        baseVersion: (unsigned int) baseVersion
+{
+  NSException *result;
+
+  result = [super saveContentString: contentString
+                  baseVersion: baseVersion];
+  if (!result && calContent)
+    {
+      [calContent release];
+      calContent = nil;
+    }
+
+  return result;
+}
+
 - (iCalCalendar *) calendar
 {
   NSString *iCalString;
index 3213aac518dbfddca0dcc600b8e734dacffa78cc..a45e744d45dac7b272bb55464937a9b0423d8bfb 100644 (file)
@@ -15,6 +15,7 @@
         "FreeBusyLookup" = ( "Owner", "Delegate", "Assistant", "FreeBusy" );
         "Add Documents, Images, and Files" = ( "Owner", "Delegate" );
         "Access Contents Information" = ( "Owner", "Delegate", "Assistant" );
+        "Delete Objects" = ( "Owner", "Organizer", "Delegate" );
       };
     };
 
index 1a5549e53fb9f5bcb03071decc9e72b64008d4a4..a56ac4267f011ed5333a52fac71f2df3ac797c42 100644 (file)
@@ -34,6 +34,8 @@
 @class NSUserDefaults;
 @class NSString;
 
+@class SOGoUser;
+
 @interface SOGoAuthenticator : SoHTTPAuthenticator
 {
   NSUserDefaults *ud;
@@ -47,6 +49,8 @@
 
 - (BOOL) LDAPCheckLogin: (NSString *) _login password: (NSString *) _pwd;
 
+- (SOGoUser *) userInContext: (WOContext *) _ctx;
+
 @end
 
 #endif /* __Main_SOGoAuthenticator_H__ */
index 18c00d2728d4cc63df332e11e240009338128dd1..2c276e06be8b6fb070779ea0383a6a541d472b47 100644 (file)
@@ -96,9 +96,9 @@ static SOGoAuthenticator *auth = nil;
 
 /* create SOGoUser */
 
-- (SoUser *) userInContext:(WOContext *)_ctx
+- (SOGoUser *) userInContext: (WOContext *)_ctx
 {
-  static SoUser *anonymous = nil, *freebusy;
+  static SOGoUser *anonymous = nil, *freebusy;
   SoUser *user;
   NSArray *traversalPath;
   NSString *login;
index 40f0abf0fc7d5f7562a6d14e7dad5e8e86c969bf..5d278097d9988f1b7624d0318e5961d9c8713f21 100644 (file)
 - (NSString *)contentForReply {
   NSArray      *keys, *partInfos;
   NSDictionary *parts, *infos;
-  SOGoMailObject *co;
 
-  co = [self clientObject];
-  keys = [co plainTextContentFetchKeys];
-  infos = [co fetchCoreInfos];
-  partInfos = [infos objectForKey: keys];
-  NSLog (@"infos: '%@'", infos);
+  keys = [[self clientObject] plainTextContentFetchKeys];
+//   SOGoMailObject *co;
+
+//   co = [self clientObject];
+//   keys = [co plainTextContentFetchKeys];
+//   infos = [co fetchCoreInfos];
+//   partInfos = [infos objectForKey: keys];
+//   NSLog (@"infos: '%@'", infos);
 
   if ([keys count] == 0)
     return nil;
index 1e83db2fd29d0aba14e22d161adde53d17dac37e..b989711f82a13732169639636e24f631e580f15e 100644 (file)
@@ -25,6 +25,8 @@
 #import <Foundation/NSDictionary.h>
 
 #import <NGObjWeb/NGObjWeb.h>
+#import <SOGo/SOGoAuthenticator.h>
+#import <NGCards/iCalEntityObject.h>
 
 @interface UIxCalInlineAptView : WOComponent
 {
     [ms appendFormat:@" apt_prio%@", prio];
   }
   email = [[[self context] activeUser] email];
-  if ((s = [appointment valueForKey:@"orgmail"])) {
-    if ([s rangeOfString:email].length > 0) {
-      [ms appendString:@" apt_organizer"];
-    }
-    else {
-      [ms appendString:@" apt_other"];
-    }
-  }
-  if ((s = [appointment valueForKey:@"partmails"])) {
-    if ([s rangeOfString:email].length > 0) {
-      [ms appendString:@" apt_participant"];
+  s = [appointment valueForKey:@"orgmail"];
+  if ([s isNotNull])
+    {
+      if ([s rangeOfString: email].length > 0)
+        [ms appendString:@" apt_organizer"];
+      else
+        [ms appendString:@" apt_other"];
     }
-    else {
-      [ms appendString:@" apt_nonparticipant"];
+  s = [appointment valueForKey:@"partmails"];
+  if ([s isNotNull])
+    {
+      if ([s rangeOfString:email].length > 0)
+        [ms appendString:@" apt_participant"];
+      else
+        [ms appendString:@" apt_nonparticipant"];
     }
-  }
   ASSIGNCOPY(style, ms);
 }
 
 
 /* helpers */
 
+- (NSString *) startHour
+{
+  NSCalendarDate *start;
+
+  start = [appointment objectForKey: @"startDate"];
+
+  return [NSString stringWithFormat: @"%.2d:%.2d",
+                   [start hourOfDay], [start minuteOfHour]];
+}
+
 - (NSString *) title
 {
   return [formatter stringForObjectValue: appointment
                            referenceDate: [self referenceDate]];
 }
 
+- (BOOL) _userIsInTheCard: (NSString *) email
+{
+  NSString *orgMailString, *partMailsString;
+  NSArray *partMails;
+  BOOL userIsInTheCard;
+
+  orgMailString = [appointment objectForKey: @"orgmail"];
+  if ([orgMailString isNotNull] && [orgMailString isEqualToString: email])
+    userIsInTheCard = YES;
+  else
+    {
+      partMailsString = [appointment objectForKey: @"partmails"];
+      if ([partMailsString isNotNull])
+        {
+          partMails = [partMailsString componentsSeparatedByString: @"\n"];
+          userIsInTheCard = [partMails containsObject: email];
+        }
+      else
+        userIsInTheCard = NO;
+    }
+
+  return userIsInTheCard;
+}
+
+- (BOOL) titleShouldBeHidden
+{
+  BOOL shouldBeHidden;
+  SOGoUser *user;
+  SOGoAuthenticator *sAuth;
+
+  sAuth = [SOGoAuthenticator sharedSOGoAuthenticator];
+  user = [sAuth userInContext: context];
+
+  if ([[appointment objectForKey: @"owner"] isEqualToString: [user login]]
+      || ([[appointment objectForKey: @"classification"] intValue]
+          != iCalAccessConfidential))
+    shouldBeHidden = NO;
+  else
+    shouldBeHidden = ![self _userIsInTheCard: [user email]];
+
+  return shouldBeHidden;
+}
+
 @end
index adf899190f3b8985a44eed0865d428d49099f1c3..74b683280949d9153a5c5db412cb1745015e788f 100644 (file)
@@ -96,49 +96,52 @@ static BOOL shouldDisplayWeekend = NO;
 - (NSArray *) filterAppointments:(NSArray *) _apts
 {
   NSMutableArray *filtered;
-  unsigned       i, count;
-  NSString       *email;
-
-  count = [_apts count];
-  if (!count) return _apts;
-  if ([self shouldDisplayRejectedAppointments]) return _apts;
-
-  filtered = [[[NSMutableArray alloc] initWithCapacity: count] autorelease];
-  email = [self emailForUser];
+  unsigned i, count;
+  NSString *email;
+  NSDictionary *info;
+  NSArray *partmails;
+  unsigned p, pCount;
+  BOOL shouldAdd;
+  NSString *partmailsString;
+  NSArray  *partstates;
+  NSString *state;
+  NSString *pEmail;
+
+  if ([self shouldDisplayRejectedAppointments])
+    return _apts;
+  {
+    count = [_apts count];
+    filtered = [[[NSMutableArray alloc] initWithCapacity: count] autorelease];
+    email = [self emailForUser];
+
+    for (i = 0; i < count; i++)
+      {
+        shouldAdd = YES;
+        info = [_apts objectAtIndex: i];
+        partmailsString = [info objectForKey: @"partmails"];
+        if ([partmailsString isNotNull])
+          {
+            partmails = [partmailsString componentsSeparatedByString: @"\n"];
+            pCount = [partmails count];
+            for (p = 0; p < pCount; p++)
+              {
+                pEmail = [partmails objectAtIndex: p];
+                if ([pEmail isEqualToString: email])
+                  {
+                    partstates = [[info objectForKey: @"partstates"]
+                                   componentsSeparatedByString: @"\n"];
+                    state = [partstates objectAtIndex: p];
+                    if ([state intValue] == iCalPersonPartStatDeclined)
+                      shouldAdd = NO;
+                    break;
+                  }
+              }
+          }
+        if (shouldAdd)
+          [filtered addObject: info];
+      }
+  }
 
-  for (i = 0; i < count; i++)
-    {
-      NSDictionary *info;
-      NSArray      *partmails;
-      unsigned     p, pCount;
-      BOOL         shouldAdd;
-    
-      shouldAdd = YES;
-      info = [_apts objectAtIndex: i];
-      partmails = [[info objectForKey: @"partmails"]
-                    componentsSeparatedByString: @"\n"];
-      pCount = [partmails count];
-      for (p = 0; p < pCount; p++)
-        {
-          NSString *pEmail;
-
-          pEmail = [partmails objectAtIndex: p];
-          if ([pEmail isEqualToString: email])
-            {
-              NSArray  *partstates;
-              NSString *state;
-
-              partstates = [[info objectForKey: @"partstates"]
-                             componentsSeparatedByString: @"\n"];
-              state = [partstates objectAtIndex: p];
-              if ([state intValue] == iCalPersonPartStatDeclined)
-                shouldAdd = NO;
-              break;
-            }
-        }
-      if (shouldAdd)
-        [filtered addObject: info];
-    }
   return filtered;
 }
 
@@ -181,7 +184,9 @@ static BOOL shouldDisplayWeekend = NO;
       if ([partmails rangeOfString: myEmail].length)
         aptFlags.canAccessApt = YES;
       else
-        aptFlags.canAccessApt = [[_apt valueForKey: @"ispublic"] boolValue];
+        aptFlags.canAccessApt
+          = ([[_apt valueForKey: @"classification"] intValue]
+             == iCalAccessPublic);
     }
 }
 
index 89544edeb7edcb07ae2271188eb4b56ec8dc31d7..7db79e75ed5ffbec9e11dc4a17aff7c190491d29 100644 (file)
 - (NSArray *) getICalPersonsFromValue: (NSString *) selectorValue;
 
 /* email, cn */
-- (NSString *)emailForUser;
-- (NSString *)cnForUser;
-
-/* restrictions */
-- (BOOL)isAccessRestricted;
+- (NSString *) emailForUser;
+- (NSString *) cnForUser;
 
 @end
 
index 08320032e55406be039f48a30f8bec89f1292bcf..20aa370d02cde043bbaf18d4b24693085f27141e 100644 (file)
   return persons;
 }
 
-- (NSString *)emailForUser {
-  return [[[self context] activeUser] email];
-}
-
-- (NSString *)cnForUser {
-  return [[[self context] activeUser] cn];
+- (NSString *) emailForUser
+{
+  return [[context activeUser] email];
 }
 
-- (BOOL)isAccessRestricted {
-  return [[self context] isAccessFromIntranet] ? NO : YES;
+- (NSString *) cnForUser
+{
+  return [[context activeUser] cn];
 }
 
 @end /* UIxComponent(Agenor) */
index 64d5c6f21266dfaf83c125ae1448860bb5d5efa7..929a66ca51d5ba714560647b51d8c1d5796a66ba 100644 (file)
@@ -1,22 +1,35 @@
 <?xml version='1.0' standalone='yes'?>
-  <div
-    var:class="displayClasses"
-    var:aptCName="appointment.c_name"
-    var:owner="appointment.owner"
-    xmlns="http://www.w3.org/1999/xhtml"
-    xmlns:var="http://www.skyrix.com/od/binding"
-    xmlns:const="http://www.skyrix.com/od/constant"
-    xmlns:rsrc="OGo:url">
-    <div class="shadow shadow1"><!-- space --></div
-      ><div class="shadow shadow2"><!-- space --></div
-      ><div class="shadow shadow3"><!-- space --></div
-      ><div class="shadow shadow4"><!-- space --></div
-      ><div var:class="innerDisplayClasses"
-      ><div class="gradient"
-        ><img rsrc:src="event-gradient.png" class="gradient"
-          /></div
-        ><div class="text"
-        ><var:string value="appointment.title" const:escapeHTML="NO"
-          /></div>
-    </div>
+<!DOCTYPE div>
+<div
+  var:class="displayClasses"
+  var:aptCName="appointment.c_name"
+  var:owner="appointment.owner"
+  xmlns="http://www.w3.org/1999/xhtml"
+  xmlns:var="http://www.skyrix.com/od/binding"
+  xmlns:const="http://www.skyrix.com/od/constant"
+  xmlns:rsrc="OGo:url">
+  <div class="shadow shadow1"><!-- space --></div
+    ><div class="shadow shadow2"><!-- space --></div
+    ><div class="shadow shadow3"><!-- space --></div
+    ><div class="shadow shadow4"><!-- space --></div
+    ><div var:class="innerDisplayClasses"
+    ><div class="gradient"
+      ><img rsrc:src="event-gradient.png" class="gradient"
+        /></div
+      ><div class="text"
+      ><span class="eventHeader"><var:string value="startHour"
+          const:escapeHTML="NO"
+          /><var:if condition="appointment.iscycle"
+          ><img rsrc:src="repeat-16.png" class="gradient"
+            /></var:if
+          ><var:if condition="appointment.hasalarm"
+          ><img rsrc:src="alarm.png" class="gradient"
+            /></var:if
+          ></span
+        ><var:if condition="titleShouldBeHidden" const:negate="YES"
+        ><br
+          /><var:string value="appointment.title" const:escapeHTML="NO"
+          /></var:if
+        ></div>
   </div>
+</div>
index d0f858b230d76dd99dae83f2c1e6e5922c846a2b..9d5daf1f5ef3c2460ec5028fef0a2a0defd4e522 100644 (file)
@@ -1162,4 +1162,13 @@ function initCalendars() {
     initCalendarContactsSelector();
 }
 
+function onSchedulerBodyKeyUp(event) {
+   if (event.which == 46) {
+      window.alert("coucou");
+      deleteEvent();
+      event.cancelBubble = true;
+   }
+}
+
 window.addEventListener("load", initCalendars, false);
+// document.body.addEventListener("keyup", onSchedulerBodyKeyUp, false);
diff --git a/UI/WebServerResources/add-user-addressbook.png b/UI/WebServerResources/add-user-addressbook.png
new file mode 100644 (file)
index 0000000..68e7a88
Binary files /dev/null and b/UI/WebServerResources/add-user-addressbook.png differ
diff --git a/UI/WebServerResources/alarm.png b/UI/WebServerResources/alarm.png
new file mode 100644 (file)
index 0000000..ae4234d
Binary files /dev/null and b/UI/WebServerResources/alarm.png differ
diff --git a/UI/WebServerResources/repeat-16.png b/UI/WebServerResources/repeat-16.png
new file mode 100644 (file)
index 0000000..44a100b
Binary files /dev/null and b/UI/WebServerResources/repeat-16.png differ