Monotone-Parent: 49f93d7885e48cc9020c68ab92841b946e9ed227
Monotone-Revision: c682c126a76f07e9f87346487cd8223169d4dca1 Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2007-11-26T17:40:44 Monotone-Branch: ca.inverse.sogomaint-2.0.2
parent
6404502eab
commit
1235af6bde
18
ChangeLog
18
ChangeLog
|
@ -1,5 +1,23 @@
|
|||
2007-11-26 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* SoObjects/Appointments/SOGoAppointmentFolder.m
|
||||
([SOGoAppointmentFolder
|
||||
-roleForComponentsWithAccessClass:accessClassforUser:uid]): cache
|
||||
acl to reduce method calls.
|
||||
([SOGoAppointmentFolder
|
||||
-fetchFields:_fieldsfromFolder:_folderfrom:_startDateto:_endDatetitle:titlecomponent:_component]):
|
||||
if the user is not the current user, we strip the useless info
|
||||
from the meta data.
|
||||
|
||||
* UI/Common/WODirectAction+SOGo.m ([WODirectAction
|
||||
-labelForKey:key]): new category method.
|
||||
|
||||
* UI/Scheduler/UIxAppointmentEditor.m ([UIxAppointmentEditor
|
||||
-event]): same as below.
|
||||
|
||||
* UI/Scheduler/UIxTaskEditor.m ([UIxTaskEditor -todo]): request a
|
||||
secured version of the component.
|
||||
|
||||
* UI/MailPartViewers/UIxMailPartViewer.m
|
||||
([-fallbackStringEncoding]): removed method.
|
||||
([UIxMailPartViewer -flatContentAsString]): we no longer use [self
|
||||
|
|
|
@ -38,6 +38,8 @@
|
|||
|
||||
#import "SOGo/SOGoGCSFolder.h"
|
||||
|
||||
#import <NGCards/iCalEntityObject.h>
|
||||
|
||||
@class NSArray;
|
||||
@class NSCalendarDate;
|
||||
@class NSException;
|
||||
|
@ -46,11 +48,12 @@
|
|||
@class NSTimeZone;
|
||||
@class GCSFolder;
|
||||
|
||||
#import <NGCards/iCalEntityObject.h>
|
||||
@interface SOGoAppointmentFolder : SOGoGCSFolder
|
||||
{
|
||||
NSTimeZone *timeZone;
|
||||
NSMutableDictionary *uidToFilename;
|
||||
NSMutableDictionary *aclMatrix;
|
||||
NSMutableArray *stripFields;
|
||||
}
|
||||
|
||||
- (BOOL) isActive;
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#import <GDLContentStore/GCSFolder.h>
|
||||
#import <DOM/DOMProtocols.h>
|
||||
#import <EOControl/EOQualifier.h>
|
||||
#import <NGCards/iCalCalendar.h>
|
||||
#import <NGCards/iCalDateTime.h>
|
||||
#import <NGCards/iCalPerson.h>
|
||||
#import <NGCards/iCalRecurrenceCalculator.h>
|
||||
|
@ -110,6 +111,9 @@ static NSNumber *sharedYes = nil;
|
|||
if ((self = [super initWithName: name inContainer: newContainer]))
|
||||
{
|
||||
timeZone = [[context activeUser] timeZone];
|
||||
aclMatrix = [NSMutableDictionary new];
|
||||
stripFields = nil;
|
||||
uidToFilename = nil;
|
||||
}
|
||||
|
||||
return self;
|
||||
|
@ -117,6 +121,8 @@ static NSNumber *sharedYes = nil;
|
|||
|
||||
- (void) dealloc
|
||||
{
|
||||
[aclMatrix release];
|
||||
[stripFields release];
|
||||
[uidToFilename release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
@ -774,6 +780,7 @@ static NSNumber *sharedYes = nil;
|
|||
{
|
||||
NSString *accessRole, *prefix, *currentRole, *suffix;
|
||||
NSEnumerator *acls;
|
||||
NSMutableDictionary *userRoles;
|
||||
|
||||
accessRole = nil;
|
||||
|
||||
|
@ -784,20 +791,74 @@ static NSNumber *sharedYes = nil;
|
|||
else
|
||||
prefix = @"Confidential";
|
||||
|
||||
acls = [[self aclsForUser: uid] objectEnumerator];
|
||||
currentRole = [acls nextObject];
|
||||
while (currentRole && !accessRole)
|
||||
if ([currentRole hasPrefix: prefix])
|
||||
{
|
||||
suffix = [currentRole substringFromIndex: [prefix length]];
|
||||
accessRole = [NSString stringWithFormat: @"Component%@", suffix];
|
||||
}
|
||||
else
|
||||
userRoles = [aclMatrix objectForKey: uid];
|
||||
if (!userRoles)
|
||||
{
|
||||
userRoles = [NSMutableDictionary dictionaryWithCapacity: 3];
|
||||
[aclMatrix setObject: userRoles forKey: uid];
|
||||
}
|
||||
|
||||
accessRole = [userRoles objectForKey: prefix];
|
||||
if (!accessRole)
|
||||
{
|
||||
acls = [[self aclsForUser: uid] objectEnumerator];
|
||||
currentRole = [acls nextObject];
|
||||
while (currentRole && !accessRole)
|
||||
if ([currentRole hasPrefix: prefix])
|
||||
{
|
||||
suffix = [currentRole substringFromIndex: [prefix length]];
|
||||
accessRole = [NSString stringWithFormat: @"Component%@", suffix];
|
||||
}
|
||||
else
|
||||
currentRole = [acls nextObject];
|
||||
if (!accessRole)
|
||||
accessRole = @"";
|
||||
[userRoles setObject: accessRole forKey: prefix];
|
||||
}
|
||||
|
||||
return accessRole;
|
||||
}
|
||||
|
||||
- (void) _buildStripFieldsFromFields: (NSArray *) fields
|
||||
{
|
||||
stripFields = [[NSMutableArray alloc] initWithCapacity: [fields count]];
|
||||
[stripFields setArray: fields];
|
||||
[stripFields removeObjectsInArray: [NSArray arrayWithObjects: @"c_name",
|
||||
@"c_uid", @"c_startdate",
|
||||
@"c_enddate", @"c_isallday",
|
||||
@"c_iscycle",
|
||||
@"c_classification",
|
||||
@"c_component", nil]];
|
||||
}
|
||||
|
||||
- (void) _fixupProtectedInformation: (NSEnumerator *) ma
|
||||
inFields: (NSArray *) fields
|
||||
forUser: (NSString *) uid
|
||||
{
|
||||
NSMutableDictionary *currentRecord;
|
||||
NSString *roles[] = {nil, nil, nil};
|
||||
iCalAccessClass accessClass;
|
||||
NSString *role;
|
||||
|
||||
if (!stripFields)
|
||||
[self _buildStripFieldsFromFields: fields];
|
||||
|
||||
while ((currentRecord = [ma nextObject]))
|
||||
{
|
||||
accessClass
|
||||
= [[currentRecord objectForKey: @"c_classification"] intValue];
|
||||
role = roles[accessClass];
|
||||
if (!role)
|
||||
{
|
||||
role = [[self roleForComponentsWithAccessClass: accessClass
|
||||
forUser: uid] substringFromIndex: 9];
|
||||
roles[accessClass] = role;
|
||||
}
|
||||
if ([role isEqualToString: @"DAndTViewer"])
|
||||
[currentRecord removeObjectsForKeys: stripFields];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSArray *) fetchFields: (NSArray *) _fields
|
||||
fromFolder: (GCSFolder *) _folder
|
||||
from: (NSCalendarDate *) _startDate
|
||||
|
@ -809,7 +870,7 @@ static NSNumber *sharedYes = nil;
|
|||
NSMutableArray *fields, *ma = nil;
|
||||
NSArray *records;
|
||||
NSString *sql, *dateSqlString, *titleSqlString, *componentSqlString,
|
||||
*privacySqlString;
|
||||
*privacySqlString, *currentLogin;
|
||||
NGCalendarDateRange *r;
|
||||
|
||||
if (_folder == nil) {
|
||||
|
@ -896,6 +957,11 @@ static NSNumber *sharedYes = nil;
|
|||
if (logger)
|
||||
[self debugWithFormat:@"returning %i records", [ma count]];
|
||||
|
||||
currentLogin = [[context activeUser] login];
|
||||
if (![currentLogin isEqualToString: owner])
|
||||
[self _fixupProtectedInformation: [ma objectEnumerator]
|
||||
inFields: _fields
|
||||
forUser: currentLogin];
|
||||
// [ma makeObjectsPerform: @selector (setObject:forKey:)
|
||||
// withObject: owner
|
||||
// withObject: @"owner"];
|
||||
|
|
|
@ -34,6 +34,8 @@
|
|||
- (WOResponse *) responseWith204;
|
||||
- (WOResponse *) redirectToLocation: (NSString *) newLocation;
|
||||
|
||||
- (NSString *) labelForKey: (NSString *) _str;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* WODIRECTACTION_SOGO_H */
|
||||
|
|
|
@ -20,10 +20,14 @@
|
|||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#import <Foundation/NSBundle.h>
|
||||
|
||||
#import <NGObjWeb/WOContext.h>
|
||||
#import <NGObjWeb/WOContext+SoObjects.h>
|
||||
#import <NGObjWeb/WOResponse.h>
|
||||
|
||||
#import <SoObjects/SOGo/NSDictionary+Utilities.h>
|
||||
#import <SoObjects/SOGo/SOGoUser.h>
|
||||
|
||||
#import "WODirectAction+SOGo.h"
|
||||
|
||||
@implementation WODirectAction (SOGoExtension)
|
||||
|
@ -53,5 +57,33 @@
|
|||
return response;
|
||||
}
|
||||
|
||||
- (NSString *) labelForKey: (NSString *) key
|
||||
{
|
||||
NSString *userLanguage, *label;
|
||||
NSArray *paths;
|
||||
NSBundle *bundle;
|
||||
NSDictionary *strings;
|
||||
|
||||
bundle = [NSBundle bundleForClass: [self class]];
|
||||
if (!bundle)
|
||||
bundle = [NSBundle mainBundle];
|
||||
|
||||
userLanguage = [[context activeUser] language];
|
||||
paths = [bundle pathsForResourcesOfType: @"strings"
|
||||
inDirectory: [NSString stringWithFormat: @"%@.lproj",
|
||||
userLanguage]
|
||||
forLocalization: userLanguage];
|
||||
if ([paths count] > 0)
|
||||
{
|
||||
strings = [NSDictionary
|
||||
dictionaryFromStringsFile: [paths objectAtIndex: 0]];
|
||||
label = [strings objectForKey: key];
|
||||
if (!label)
|
||||
label = key;
|
||||
}
|
||||
else
|
||||
label = key;
|
||||
|
||||
return label;
|
||||
}
|
||||
@end
|
||||
|
|
|
@ -489,12 +489,6 @@ static BOOL uixDebugEnabled = NO;
|
|||
if ([lTable hasPrefix:@"$"])
|
||||
lTable = [self valueForKeyPath:[lTable substringFromIndex:1]];
|
||||
|
||||
#if 0
|
||||
if ([lVal hasPrefix:@"$"])
|
||||
lVal = [self valueForKeyPath:[lVal substringFromIndex:1]];
|
||||
|
||||
#endif
|
||||
|
||||
/* lookup string */
|
||||
return [rm stringForKey: lKey
|
||||
inTableNamed: lTable
|
||||
|
|
|
@ -413,5 +413,13 @@ validate_endbeforestart = "Enddate is before startdate!";
|
|||
"Location" = "Location";
|
||||
"(Private Event)" = "(Private Event)";
|
||||
|
||||
vevent_class0 = "(Public event)";
|
||||
vevent_class1 = "(Private event)";
|
||||
vevent_class2 = "(Confidential event)";
|
||||
|
||||
vtodo_class0 = "(Public task)";
|
||||
vtodo_class1 = "(Private task)";
|
||||
vtodo_class2 = "(Confidential task)";
|
||||
|
||||
"closeThisWindowMessage" = "Thank you! You may now close this window or view your ";
|
||||
"Multicolumn Day View" = "Multicolumn Day View";
|
||||
|
|
|
@ -412,5 +412,13 @@ validate_endbeforestart = "La date de fin est avant la date de début !";
|
|||
"Location" = "Lieu";
|
||||
"(Private Event)" = "(Événement privé)";
|
||||
|
||||
vevent_class0 = "(Événement public)";
|
||||
vevent_class1 = "(Événement privé)";
|
||||
vevent_class2 = "(Événement confidentiel)";
|
||||
|
||||
vtodo_class0 = "(Tâche publique)";
|
||||
vtodo_class1 = "(Tâche privée)";
|
||||
vtodo_class2 = "(Tâche confidentielle)";
|
||||
|
||||
"closeThisWindowMessage" = "Merci! Vous pouvez maintenant fermer cette fenêtre ou consulter votre ";
|
||||
"Multicolumn Day View" = "Multicolonne";
|
||||
|
|
|
@ -400,5 +400,14 @@ validate_endbeforestart = "Ihr Beginn ist nach dem Ende";
|
|||
"Location" = "Ort";
|
||||
"(Private Event)" = "(Privater Termin)";
|
||||
|
||||
/* event list */
|
||||
vevent_class0 = "(Public event)";
|
||||
vevent_class1 = "(Private event)";
|
||||
vevent_class2 = "(Confidential event)";
|
||||
|
||||
vtodo_class0 = "(Public task)";
|
||||
vtodo_class1 = "(Private task)";
|
||||
vtodo_class2 = "(Confidential task)";
|
||||
|
||||
"closeThisWindowMessage" = "Vielen Dank! Sie können dieses Fenster jetzt schließen.";
|
||||
"Multicolumn Day View" = "Multicolonne";
|
||||
|
|
|
@ -71,7 +71,7 @@
|
|||
{
|
||||
if (!event)
|
||||
{
|
||||
event = (iCalEvent *) [[self clientObject] component: NO secure: NO];
|
||||
event = (iCalEvent *) [[self clientObject] component: NO secure: YES];
|
||||
[event retain];
|
||||
}
|
||||
|
||||
|
@ -270,7 +270,7 @@
|
|||
unsigned int minutes;
|
||||
iCalRecurrenceRule *rule;
|
||||
|
||||
event = (iCalEvent *) [[self clientObject] component: NO secure: YES];
|
||||
[self event];
|
||||
if (event)
|
||||
{
|
||||
startDate = [event startDate];
|
||||
|
@ -382,7 +382,7 @@
|
|||
iCalRecurrenceRule *rule;
|
||||
|
||||
clientObject = [self clientObject];
|
||||
event = (iCalEvent *) [clientObject component: YES secure: NO];
|
||||
[self event];
|
||||
|
||||
[super takeValuesFromRequest: _rq inContext: _ctx];
|
||||
|
||||
|
|
|
@ -23,8 +23,7 @@
|
|||
#ifndef UIXCALLISTINGACTIONVIEW_H
|
||||
#define UIXCALLISTINGACTIONVIEW_H
|
||||
|
||||
|
||||
#import <NGObjWeb/WODirectAction.h>
|
||||
#import <Common/WODirectAction+SOGo.h>
|
||||
|
||||
@class NSCalendarDate;
|
||||
@class NSMutableDictionary;
|
||||
|
|
|
@ -185,22 +185,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
- (void) _updatePrivacyInComponent: (NSMutableDictionary *) component
|
||||
fromFolder: (SOGoAppointmentFolder *) folder
|
||||
{
|
||||
int privacyFlag;
|
||||
NSString *roleString;
|
||||
|
||||
privacyFlag = [[component objectForKey: @"classification"] intValue];
|
||||
roleString = [folder roleForComponentsWithAccessClass: privacyFlag
|
||||
forUser: userLogin];
|
||||
if ([roleString isEqualToString: @"ComponentDAndTViewer"])
|
||||
{
|
||||
[component setObject: @"" forKey: @"c_title"];
|
||||
[component setObject: @"" forKey: @"c_location"];
|
||||
}
|
||||
}
|
||||
|
||||
- (SOGoAppointmentFolder *) _aptFolder: (NSString *) folder
|
||||
withClientObject: (SOGoAppointmentFolder *) clientObject
|
||||
{
|
||||
|
@ -220,6 +204,17 @@
|
|||
return aptFolder;
|
||||
}
|
||||
|
||||
- (void) _fixComponentTitle: (NSMutableDictionary *) component
|
||||
withType: (NSString *) type
|
||||
{
|
||||
NSString *labelKey;
|
||||
|
||||
labelKey = [NSString stringWithFormat: @"%@_class%@",
|
||||
type, [component objectForKey: @"c_classification"]];
|
||||
[component setObject: [self labelForKey: labelKey]
|
||||
forKey: @"c_title"];
|
||||
}
|
||||
|
||||
- (NSArray *) _fetchFields: (NSArray *) fields
|
||||
forComponentOfType: (NSString *) component
|
||||
{
|
||||
|
@ -232,28 +227,29 @@
|
|||
|
||||
marker = [NSNull null];
|
||||
|
||||
clientObject = [self clientObject];
|
||||
clientObject = [self clientObject];
|
||||
|
||||
folders = [[clientObject subFolders] objectEnumerator];
|
||||
currentFolder = [folders nextObject];
|
||||
|
||||
infos = [NSMutableArray array];
|
||||
|
||||
while (currentFolder)
|
||||
{
|
||||
if ([currentFolder isActive])
|
||||
{
|
||||
currentInfos = [[currentFolder fetchCoreInfosFrom: startDate
|
||||
to: endDate
|
||||
title: title
|
||||
component: component] objectEnumerator];
|
||||
currentInfos
|
||||
= [[currentFolder fetchCoreInfosFrom: startDate
|
||||
to: endDate
|
||||
title: title
|
||||
component: component] objectEnumerator];
|
||||
|
||||
while ((newInfo = [currentInfos nextObject]))
|
||||
{
|
||||
[self _updatePrivacyInComponent: newInfo
|
||||
fromFolder: currentFolder];
|
||||
[newInfo setObject: [currentFolder nameInContainer]
|
||||
forKey: @"c_folder"];
|
||||
|
||||
if (![[newInfo objectForKey: @"c_title"] length])
|
||||
[self _fixComponentTitle: newInfo withType: component];
|
||||
[infos addObject: [newInfo objectsForKeys: fields
|
||||
notFoundMarker: marker]];
|
||||
}
|
||||
|
@ -323,7 +319,7 @@
|
|||
newEvents = [NSMutableArray array];
|
||||
fields = [NSArray arrayWithObjects: @"c_name", @"c_folder", @"c_status",
|
||||
@"c_title", @"c_startdate", @"c_enddate", @"c_location",
|
||||
@"c_isallday", nil];
|
||||
@"c_isallday", @"c_classification", nil];
|
||||
events = [[self _fetchFields: fields
|
||||
forComponentOfType: @"vevent"] objectEnumerator];
|
||||
oldEvent = [events nextObject];
|
||||
|
@ -399,7 +395,7 @@
|
|||
[self _setupContext];
|
||||
|
||||
fields = [NSArray arrayWithObjects: @"c_name", @"c_folder", @"c_status",
|
||||
@"c_title", @"c_enddate", nil];
|
||||
@"c_title", @"c_enddate", @"c_classification", nil];
|
||||
|
||||
tasks = [[self _fetchFields: fields
|
||||
forComponentOfType: @"vtodo"] objectEnumerator];
|
||||
|
|
|
@ -73,7 +73,7 @@
|
|||
{
|
||||
if (!todo)
|
||||
{
|
||||
todo = (iCalToDo *) [[self clientObject] component: NO secure: NO];
|
||||
todo = (iCalToDo *) [[self clientObject] component: NO secure: YES];
|
||||
[todo retain];
|
||||
}
|
||||
|
||||
|
@ -289,7 +289,7 @@
|
|||
NSString *duration;
|
||||
unsigned int minutes;
|
||||
|
||||
todo = (iCalToDo *) [[self clientObject] component: NO secure: YES];
|
||||
[self todo];
|
||||
if (todo)
|
||||
{
|
||||
startDate = [todo startDate];
|
||||
|
@ -383,10 +383,7 @@
|
|||
- (void) takeValuesFromRequest: (WORequest *) _rq
|
||||
inContext: (WOContext *) _ctx
|
||||
{
|
||||
SOGoTaskObject *clientObject;
|
||||
|
||||
clientObject = [self clientObject];
|
||||
todo = (iCalToDo *) [clientObject component: YES secure: NO];
|
||||
[self todo];
|
||||
|
||||
[super takeValuesFromRequest: _rq inContext: _ctx];
|
||||
|
||||
|
@ -438,12 +435,9 @@
|
|||
|
||||
- (id) changeStatusAction
|
||||
{
|
||||
SOGoTaskObject *clientObject;
|
||||
NSString *newStatus;
|
||||
|
||||
clientObject = [self clientObject];
|
||||
todo = (iCalToDo *) [clientObject component: NO secure: NO];
|
||||
[todo retain];
|
||||
[self todo];
|
||||
if (todo)
|
||||
{
|
||||
newStatus = [self queryParameterForKey: @"status"];
|
||||
|
@ -455,7 +449,7 @@
|
|||
[todo setPercentComplete: @"0"];
|
||||
[todo setStatus: @"IN-PROCESS"];
|
||||
}
|
||||
[clientObject saveComponent: todo];
|
||||
[[self clientObject] saveComponent: todo];
|
||||
}
|
||||
|
||||
return [self responseWith204];
|
||||
|
|
|
@ -356,12 +356,12 @@ function eventsListCallback(http) {
|
|||
td = document.createElement("td");
|
||||
row.appendChild(td);
|
||||
Event.observe(td, "mousedown", listRowMouseDownHandler, true);
|
||||
td.appendChild(document.createTextNode(data[i][8]));
|
||||
td.appendChild(document.createTextNode(data[i][9]));
|
||||
|
||||
td = document.createElement("td");
|
||||
row.appendChild(td);
|
||||
Event.observe(td, "mousedown", listRowMouseDownHandler, true);
|
||||
td.appendChild(document.createTextNode(data[i][9]));
|
||||
td.appendChild(document.createTextNode(data[i][10]));
|
||||
|
||||
td = document.createElement("td");
|
||||
row.appendChild(td);
|
||||
|
|
Loading…
Reference in New Issue