02111-1307, USA.
*/
-#include "UIxComponent.h"
-#include "SOGoJSStringFormatter.h"
-#include "common.h"
-#include <NGObjWeb/SoHTTPAuthenticator.h>
+#import "SOGoJSStringFormatter.h"
+#import "common.h"
+
+#import <NGObjWeb/SoHTTPAuthenticator.h>
+#import <NGObjWeb/WOResourceManager.h>
+
+#import <SOGo/NSString+URL.h>
+
+#import <SOGo/SOGoUser.h>
+#import <SOGo/SOGoObject.h>
+#import <SOGo/SOGoCustomGroupFolder.h>
+#import <SOGo/NSCalendarDate+SOGo.h>
+
+#import "../Common/UIxJSClose.h"
+
+#import "UIxComponent.h"
@interface UIxComponent (PrivateAPI)
- (void)_parseQueryString:(NSString *)_s;
@implementation UIxComponent
-static NSTimeZone *MET = nil;
-static NSTimeZone *GMT = nil;
-
static NSMutableArray *dayLabelKeys = nil;
static NSMutableArray *abbrDayLabelKeys = nil;
static NSMutableArray *monthLabelKeys = nil;
uixDebugEnabled = [ud boolForKey:@"SOGoUIxDebugEnabled"];
- if (MET == nil) {
- MET = [[NSTimeZone timeZoneWithAbbreviation:@"MET"] retain];
- GMT = [[NSTimeZone timeZoneWithAbbreviation:@"GMT"] retain];
- }
if (dayLabelKeys == nil) {
dayLabelKeys = [[NSMutableArray alloc] initWithCapacity:7];
[dayLabelKeys addObject:@"Sunday"];
}
}
-- (void)dealloc {
+- (id) init
+{
+ if ((self = [super init]))
+ {
+ _selectedDate = nil;
+ }
+
+ return self;
+}
+
+- (void) dealloc
+{
[self->queryParameters release];
+ if (_selectedDate)
+ [_selectedDate release];
[super dealloc];
}
/* query parameters */
-- (void)_parseQueryString:(NSString *)_s {
+- (void) _parseQueryString: (NSString *) _s
+{
NSEnumerator *e;
NSString *part;
-
+ NSRange r;
+ NSString *key, *value;
+
e = [[_s componentsSeparatedByString:@"&"] objectEnumerator];
- while ((part = [e nextObject]) != nil) {
- NSRange r;
- NSString *key, *value;
-
- r = [part rangeOfString:@"="];
- if (r.length == 0) {
+ part = [e nextObject];
+ while (part)
+ {
+ r = [part rangeOfString:@"="];
+ if (r.length == 0)
+ {
/* missing value of query parameter */
- key = [part stringByUnescapingURL];
- value = @"1";
- }
- else {
- key = [[part substringToIndex:r.location] stringByUnescapingURL];
- value = [[part substringFromIndex:(r.location + r.length)]
- stringByUnescapingURL];
+ key = [part stringByUnescapingURL];
+ value = @"1";
+ }
+ else
+ {
+ key = [[part substringToIndex:r.location] stringByUnescapingURL];
+ value = [[part substringFromIndex:(r.location + r.length)]
+ stringByUnescapingURL];
+ }
+ [self->queryParameters setObject:value forKey:key];
+ part = [e nextObject];
}
- [self->queryParameters setObject:value forKey:key];
- }
}
-- (void)addKeepAliveFormValuesToQueryParameters {
+
+- (void) addKeepAliveFormValuesToQueryParameters
+{
}
-- (NSString *)queryParameterForKey:(NSString *)_key {
+- (NSString *) queryParameterForKey: (NSString *) _key
+{
return [[self _queryParameters] objectForKey:_key];
}
-- (void)setQueryParameter:(NSString *)_param forKey:(NSString *)_key {
- if(_key == nil)
- return;
-
- if(_param != nil)
- [[self _queryParameters] setObject:_param forKey:_key];
- else
- [[self _queryParameters] removeObjectForKey:_key];
+- (void) setQueryParameter: (NSString *) _param
+ forKey: (NSString *) _key
+{
+ if (_key)
+ {
+ if (_param)
+ [[self _queryParameters] setObject: _param forKey: _key];
+ else
+ [[self _queryParameters] removeObjectForKey: _key];
+ }
}
-- (NSMutableDictionary *)_queryParameters {
+- (NSMutableDictionary *) _queryParameters
+{
// TODO: this code is weird, should use WORequest methods for parsing
WORequest *req;
NSString *uri;
NSRange r;
+ NSString *qs;
if (self->queryParameters)
return self->queryParameters;
self->queryParameters = [[NSMutableDictionary alloc] initWithCapacity:8];
-
+
req = [[self context] request];
uri = [req uri];
r = [uri rangeOfString:@"?" options:NSBackwardsSearch];
- if (r.length > 0) {
- NSString *qs;
-
- qs = [uri substringFromIndex:NSMaxRange(r)];
- [self _parseQueryString:qs];
- }
+ if (r.length > 0)
+ {
+ qs = [uri substringFromIndex:NSMaxRange(r)];
+ [self _parseQueryString:qs];
+ }
/* add form values */
[self addKeepAliveFormValuesToQueryParameters];
return self->queryParameters;
}
-- (NSDictionary *)queryParameters {
+- (NSDictionary *) queryParameters
+{
return [self _queryParameters];
}
-- (NSDictionary *)queryParametersBySettingSelectedDate:(NSCalendarDate *)_date{
+- (NSDictionary *) queryParametersBySettingSelectedDate: (NSCalendarDate *) _date
+{
NSMutableDictionary *qp;
qp = [[self queryParameters] mutableCopy];
return [qp autorelease];
}
-- (void)setSelectedDateQueryParameter:(NSCalendarDate *)_newDate
- inDictionary:(NSMutableDictionary *)_qp;
+- (void) setSelectedDateQueryParameter: (NSCalendarDate *) _newDate
+ inDictionary: (NSMutableDictionary *) _qp
{
- if(_newDate != nil)
- [_qp setObject:[self dateStringForDate:_newDate] forKey:@"day"];
+ if (_newDate)
+ [_qp setObject: [self dateStringForDate: _newDate] forKey: @"day"];
else
[_qp removeObjectForKey:@"day"];
}
-- (NSString *)completeHrefForMethod:(NSString *)_method {
- WOContext *ctx;
+- (NSString *) completeHrefForMethod: (NSString *) _method
+{
+ WOContext *ctx;
NSDictionary *qp;
- NSString *qs, *qps;
+ NSString *qs, *qps, *href;
qp = [self queryParameters];
- if([qp count] == 0)
- return _method;
+ if ([qp count] > 0)
+ {
+ ctx = [self context];
+ qps = [ctx queryPathSeparator];
+ [ctx setQueryPathSeparator: @"&"];
+ qs = [ctx queryStringFromDictionary: qp];
+ [ctx setQueryPathSeparator: qps];
+ href = [_method stringByAppendingFormat:@"?%@", qs];
+ }
+ else
+ href = _method;
- ctx = [self context];
- qps = [ctx queryPathSeparator];
- [ctx setQueryPathSeparator:@"&"];
- qs = [ctx queryStringFromDictionary:qp];
- [ctx setQueryPathSeparator:qps];
- return [_method stringByAppendingFormat:@"?%@", qs];
+ return href;
}
-- (NSString *)ownMethodName {
+- (NSString *) ownMethodName
+{
NSString *uri;
NSRange r;
/* next: strip trailing slash */
- if ([uri hasSuffix:@"/"]) uri = [uri substringToIndex:([uri length] - 1)];
- r = [uri rangeOfString:@"/" options:NSBackwardsSearch];
+ if ([uri hasSuffix: @"/"])
+ uri = [uri substringToIndex: ([uri length] - 1)];
+ r = [uri rangeOfString:@"/" options: NSBackwardsSearch];
/* then: cut of last path component */
if (r.length == 0) // no slash? are we at root?
return @"/";
- return [uri substringFromIndex:(r.location + 1)];
+ return [uri substringFromIndex: (r.location + 1)];
}
-- (NSString *)userFolderPath {
+- (NSString *) userFolderPath
+{
WOContext *ctx;
- NSArray *traversalObjects;
- NSString *url;
- NSString *path;
+ NSString *url, *path;
+ NSEnumerator *objects;
+ SOGoObject *currentObject;
+ BOOL found;
ctx = [self context];
- traversalObjects = [ctx objectTraversalStack];
- url = [[traversalObjects objectAtIndex:0]
- baseURLInContext:ctx];
+ objects = [[ctx objectTraversalStack] objectEnumerator];
+ currentObject = [objects nextObject];
+ found = NO;
+ while (currentObject
+ && !found)
+ if ([currentObject isKindOfClass: [SOGoUserFolder class]])
+ found = YES;
+ else
+ currentObject = [objects nextObject];
+
+ url = [currentObject baseURLInContext:ctx];
path = [[NSURL URLWithString:url] path];
- path = [path stringByAppendingPathComponent:[[ctx activeUser] login]];
+
return path;
}
-- (NSString *)ownPath {
+- (NSString *) applicationPath
+{
+ SOGoObject *currentClient, *parent;
+ NSString *url;
+ BOOL found;
+ Class objectClass, groupFolderClass, userFolderClass;
+ WOContext *ctx;
+
+ groupFolderClass = [SOGoCustomGroupFolder class];
+ userFolderClass = [SOGoUserFolder class];
+
+ currentClient = [self clientObject];
+ objectClass = [currentClient class];
+ found = (objectClass == groupFolderClass || objectClass == userFolderClass);
+ while (!found && currentClient)
+ {
+ parent = [currentClient container];
+ objectClass = [parent class];
+ if (objectClass == groupFolderClass
+ || objectClass == userFolderClass)
+ found = YES;
+ else
+ currentClient = parent;
+ }
+
+ ctx = [self context];
+ url = [currentClient baseURLInContext: ctx];
+
+ return [[NSURL URLWithString: url] path];
+}
+
+- (NSString *) resourcesPath
+{
+ WOResourceManager *rm;
+
+ if ((rm = [self resourceManager]) == nil)
+ rm = [[WOApplication application] resourceManager];
+
+ return [rm webServerResourcesPath];
+}
+
+- (NSString *) ownPath
+{
NSString *uri;
NSRange r;
r = [uri rangeOfString:@"?" options:NSBackwardsSearch];
if (r.length > 0)
uri = [uri substringToIndex:r.location];
+
return uri;
}
-- (NSString *)relativePathToUserFolderSubPath:(NSString *)_sub {
+- (NSString *) relativePathToUserFolderSubPath: (NSString *) _sub
+{
NSString *dst, *rel;
dst = [[self userFolderPath] stringByAppendingPathComponent:_sub];
rel = [dst urlPathRelativeToPath:[self ownPath]];
+
return rel;
}
-
-/* date */
-- (NSTimeZone *)viewTimeZone {
- // Note: also in the folder, should be based on a cookie?
- return MET;
-}
+- (NSCalendarDate *) selectedDate
+{
+ if (!_selectedDate)
+ {
+ _selectedDate
+ = [NSCalendarDate
+ dateFromShortDateString: [self queryParameterForKey: @"day"]
+ andShortTimeString: [self queryParameterForKey: @"hm"]
+ inTimeZone: [[self clientObject] userTimeZone]];
+ [_selectedDate retain];
+ }
-- (NSTimeZone *)backendTimeZone {
- return GMT;
+ return _selectedDate;
}
-- (NSCalendarDate *)selectedDate {
- NSString *s;
- NSCalendarDate *cdate;
-
- s = [self queryParameterForKey:@"day"];
- cdate = ([s length] > 0)
- ? [self dateForDateString:s]
- : [NSCalendarDate date];
- [cdate setTimeZone:[self viewTimeZone]];
- s = [self queryParameterForKey:@"hm"];
- if([s length] == 4) {
- unsigned hour, minute;
-
- hour = [[s substringToIndex:2] unsignedIntValue];
- minute = [[s substringFromIndex:2] unsignedIntValue];
- cdate = [cdate hour:hour minute:minute];
- }
- else {
- cdate = [cdate hour:12 minute:0];
- }
- return cdate;
-}
+- (NSString *) dateStringForDate: (NSCalendarDate *) _date
+{
+ [_date setTimeZone: [[self clientObject] userTimeZone]];
-- (NSString *)dateStringForDate:(NSCalendarDate *)_date {
- [_date setTimeZone:[self viewTimeZone]];
return [_date descriptionWithCalendarFormat:@"%Y%m%d"];
}
-- (NSCalendarDate *)dateForDateString:(NSString *)_dateString {
- return [NSCalendarDate dateWithString:_dateString
- calendarFormat:@"%Y%m%d"];
+- (BOOL) hideFrame
+{
+ return ([[self queryParameterForKey: @"noframe"] boolValue]);
}
+- (UIxComponent *) jsCloseWithRefreshMethod: (NSString *) methodName
+{
+ UIxJSClose *jsClose;
+
+ jsClose = [UIxJSClose new];
+ [jsClose autorelease];
+ [jsClose setRefreshMethod: methodName];
+
+ return jsClose;
+}
/* SoUser */
-- (SoUser *)user {
+- (SoUser *) user
+{
WOContext *ctx;
ctx = [self context];
- return [[[self clientObject] authenticatorInContext:ctx] userInContext:ctx];
+
+ return [[[self clientObject] authenticatorInContext: ctx] userInContext: ctx];
}
-- (NSString *)shortUserNameForDisplay {
+- (NSString *) shortUserNameForDisplay
+{
// TODO: better use a SoUser formatter?
// TODO: who calls that?
NSString *s;
/* labels */
-- (NSString *)labelForKey:(NSString *)_str {
+- (NSString *) labelForKey: (NSString *) _str
+{
WOResourceManager *rm;
- NSArray *languages;
- NSString *label;
- NSString *lKey, *lTable, *lVal;
+ NSArray *languages;
+ NSString *lKey, *lTable, *lVal;
NSRange r;
if ([_str length] == 0)
/* find resource manager */
- if ((rm = [self resourceManager]) == nil)
+ if ((rm = [self pageResourceManager]) == nil)
rm = [[WOApplication application] resourceManager];
if (rm == nil)
[self warnWithFormat:@"missing resource manager!"];
#endif
/* lookup string */
-
- label = [rm stringForKey:lKey inTableNamed:lTable withDefaultValue:lVal
- languages:languages];
- return label;
+ return [rm stringForKey: lKey
+ inTableNamed: lTable
+ withDefaultValue: lVal
+ languages: languages];
}
-- (NSString *)localizedNameForDayOfWeek:(unsigned)_dayOfWeek {
+- (NSString *) localizedNameForDayOfWeek:(unsigned)_dayOfWeek {
NSString *key = [dayLabelKeys objectAtIndex:_dayOfWeek % 7];
return [self labelForKey:key];
}
return [[self context] valueForKey:@"locale"];
}
+- (WOResourceManager *) pageResourceManager
+{
+ WOResourceManager *rm;
+
+ if ((rm = [[[self context] page] resourceManager]) == nil)
+ rm = [[WOApplication application] resourceManager];
+
+ return rm;
+}
+
+- (NSString *) urlForResourceFilename: (NSString *) filename
+{
+ static NSMutableDictionary *pageToURL = nil;
+ NSString *url;
+ WOComponent *page;
+ WOResourceManager *rm;
+ NSBundle *pageBundle;
+
+ if (filename)
+ {
+ if (!pageToURL)
+ pageToURL = [[NSMutableDictionary alloc] initWithCapacity: 32];
+
+ url = [pageToURL objectForKey: filename];
+ if (!url)
+ {
+ rm = [self pageResourceManager];
+ page = [[self context] page];
+ pageBundle = [NSBundle bundleForClass: [page class]];
+ url = [rm urlForResourceNamed: filename
+ inFramework: [pageBundle bundlePath]
+ languages: nil
+ request: [[self context] request]];
+ if (!url)
+ url = @"";
+ else
+ if ([url hasPrefix: @"http"])
+ url = [url hostlessURL];
+ [pageToURL setObject: url forKey: filename];
+ }
+
+// NSLog (@"url for '%@': '%@'", filename, url);
+ }
+ else
+ url = @"";
+
+ return url;
+}
+
/* debugging */
- (BOOL)isUIxDebugEnabled {