diff --git a/UI/Contacts/French.lproj/Localizable.strings b/UI/Contacts/French.lproj/Localizable.strings index 00ccd6700..f6a443be8 100644 --- a/UI/Contacts/French.lproj/Localizable.strings +++ b/UI/Contacts/French.lproj/Localizable.strings @@ -29,3 +29,6 @@ "edit" = "Editer"; "invalidemailwarn" = "Champ de l'email invalide, continuer quand même ?"; "new" = "Nouveau"; + +"Name or Address" = "Le nom ou l'adresse"; +"Personal Addressbook" = "Adresses personnelles"; diff --git a/UI/Contacts/GNUmakefile b/UI/Contacts/GNUmakefile index 2e4924638..67ee9889d 100644 --- a/UI/Contacts/GNUmakefile +++ b/UI/Contacts/GNUmakefile @@ -14,7 +14,6 @@ ContactsUI_OBJC_FILES = \ \ ContactsUIProduct.m \ UIxContactsFilterPanel.m \ - UIxContactsSelectionView.m \ UIxContactView.m \ UIxContactSelector.m \ UIxContactEditor.m \ diff --git a/UI/Contacts/UIxContactEditorBase.m b/UI/Contacts/UIxContactEditorBase.m index 09d17f83b..5f1bf6c4d 100644 --- a/UI/Contacts/UIxContactEditorBase.m +++ b/UI/Contacts/UIxContactEditorBase.m @@ -19,11 +19,12 @@ 02111-1307, USA. */ -#include "UIxContactEditorBase.h" #include #include #include "common.h" +#include "UIxContactEditorBase.h" + @implementation UIxContactEditorBase - (id)init { @@ -43,9 +44,11 @@ /* accessors */ -- (void)setContentString:(NSString *)_cstr { +- (void)setContentString:(NSString *)_cstr +{ ASSIGNCOPY(self->contentString, _cstr); } + - (NSString *)contentString { return self->contentString; } @@ -185,31 +188,36 @@ - (void) initSnapshot { - NSString *c; + NGVCard *vCard; /* load iCalendar file */ - c = [[self clientObject] contentAsString]; - if ([c length] == 0) /* a new contact */ - c = [self contentStringTemplate]; - - [self setContentString:c]; - [self loadValuesFromContentString:c]; + vCard = [[self clientObject] vCard]; + if (vCard) +// if ([c length] == 0) /* a new contact */ +// c = [self contentStringTemplate]; + { +// [self setContent: record]; +// [self loadValuesFromContentString: record]; + } } -- (id)defaultAction { +- (id ) defaultAction +{ // TODO: very similiar to apt-editor (apt editor would need to use std names [self initSnapshot]; return self; } -- (NSString *)viewActionName { +- (NSString *) viewActionName +{ /* this is overridden in the mail based contacts UI to redirect to tb.edit */ return @""; } -- (NSString *)editActionName { +- (NSString *) editActionName +{ /* this is overridden in the mail based contacts UI to redirect to tb.edit */ return @"edit"; } @@ -218,48 +226,48 @@ { NSException *ex; NSString *uri; - NSDictionary *record; +// NSDictionary *record; NSMutableDictionary *newRecord; - if ([[self clientObject] - respondsToSelector: @selector (saveContentString:)]) - { - if (contentString) - { - record = [contentString propertyList]; - if (record) - { - newRecord = [[record mutableCopy] autorelease]; - [self saveValuesIntoRecord: newRecord]; - ex = [[self clientObject] saveRecord: newRecord]; - if (ex) - { - [self setErrorText: [ex reason]]; +// if ([[self clientObject] +// respondsToSelector: @selector (saveContentString:)]) +// { +// if (contentString) +// { +// record = [contentString propertyList]; +// if (record) +// { +// newRecord = [[record mutableCopy] autorelease]; +// [self saveValuesIntoRecord: newRecord]; +// ex = [[self clientObject] saved]; +// if (ex) +// { +// [self setErrorText: [ex reason]]; - return self; - } - else - { - uri = [self viewActionName]; - if ([uri length] <= 0) - uri = @".."; +// return self; +// } +// else +// { +// uri = [self viewActionName]; +// if ([uri length] <= 0) +// uri = @".."; - return [self redirectToLocation: [self _completeURIForMethod: uri]]; - } - } - else - { - [self setErrorText: @"Invalid property list data ..."]; // localize - return self; - } - } - else - { - [self setErrorText: @"Missing object content!"]; // localize - return self; - } - } - else +// return [self redirectToLocation: [self _completeURIForMethod: uri]]; +// } +// } +// else +// { +// [self setErrorText: @"Invalid property list data ..."]; // localize +// return self; +// } +// } +// else +// { +// [self setErrorText: @"Missing object content!"]; // localize +// return self; +// } +// } +// else return [NSException exceptionWithHTTPStatus: 400 /* Bad Request */ reason: @"method cannot be invoked on " @"the specified object"]; diff --git a/UI/Contacts/UIxContactView.m b/UI/Contacts/UIxContactView.m index 08abd7e5c..f92b886f5 100644 --- a/UI/Contacts/UIxContactView.m +++ b/UI/Contacts/UIxContactView.m @@ -75,18 +75,20 @@ /* action */ - (id)defaultAction { - if ([[self clientObject] record] == nil) { + if ([[self clientObject] vCard] == nil) { return [NSException exceptionWithHTTPStatus:404 /* Not Found */ reason:@"could not locate contact"]; } return self; } -- (BOOL)isDeletableClientObject { - return [[self clientObject] respondsToSelector:@selector(delete)]; +- (BOOL) isDeletableClientObject +{ + return [[self clientObject] respondsToSelector: @selector(delete)]; } -- (id)deleteAction { +- (id) deleteAction +{ NSException *ex; id url; diff --git a/UI/Contacts/UIxContactsFilterPanel.m b/UI/Contacts/UIxContactsFilterPanel.m index 6dc385f0c..f08c6abc9 100644 --- a/UI/Contacts/UIxContactsFilterPanel.m +++ b/UI/Contacts/UIxContactsFilterPanel.m @@ -19,9 +19,9 @@ 02111-1307, USA. */ -#include +#include -@interface UIxContactsFilterPanel : WOComponent +@interface UIxContactsFilterPanel : UIxComponent { NSString *searchText; NSString *searchCriteria; @@ -36,10 +36,10 @@ static NSArray *filters = nil; -+ (void)initialize { ++ (void) initialize +{ NSMutableDictionary *md; NSMutableArray *ma; - unsigned i; md = [[NSMutableDictionary alloc] initWithCapacity:8]; ma = [[NSMutableArray alloc] initWithCapacity:4]; @@ -60,7 +60,8 @@ static NSArray *filters = nil; return self; } -- (void)dealloc { +- (void) dealloc +{ [self->searchCriteria release]; [self->searchText release]; [super dealloc]; @@ -68,34 +69,30 @@ static NSArray *filters = nil; /* accessors */ -- (void)setSearchText: (NSString *)_txt +- (void) setSearchText: (NSString *)_txt { ASSIGNCOPY(self->searchText, _txt); } -- (void)setSearchCriteria: (NSString *)_txt +- (void) setSearchCriteria: (NSString *)_txt { ASSIGNCOPY(self->searchText, _txt); } -- (NSString *)searchText +- (NSString *) searchText { - if (self->searchText == nil) - { - self->searchText = - [[[[self context] request] formValueForKey:@"search"] copy]; - } - return self->searchText; + if (!searchText) + searchText = [[self queryParameterForKey: @"search"] copy]; + + return searchText; } -- (NSString *)searchCriteria +- (NSString *) searchCriteria { - if (self->searchCriteria == nil) - { - self->searchCriteria = - [[[[self context] request] formValueForKey:@"criteria"] copy]; - } - return self->searchCriteria; + if (!searchCriteria) + searchCriteria = [[self queryParameterForKey: @"criteria"] copy]; + + return searchCriteria; } /* filters */ @@ -118,7 +115,7 @@ static NSArray *filters = nil; - (NSString *) selectedFilter { - return [[[self context] request] formValueForKey: @"filterpopup"]; + return [self queryParameterForKey: @"filterpopup"]; } @end /* UIxContactsFilterPanel */ diff --git a/UI/Contacts/UIxContactsListViewBase.h b/UI/Contacts/UIxContactsListViewBase.h index 8205f9bef..42b512ed0 100644 --- a/UI/Contacts/UIxContactsListViewBase.h +++ b/UI/Contacts/UIxContactsListViewBase.h @@ -22,16 +22,16 @@ #ifndef __UIxContactsListViewBase_H__ #define __UIxContactsListViewBase_H__ -#include +#import -@class NSString, NSArray; +@class NSString; + +@protocol SOGoContactObject; @interface UIxContactsListViewBase : UIxComponent { - NSArray *allRecords; - NSArray *filteredRecords; NSString *searchText; - id contact; + id currentContact; } @end diff --git a/UI/Contacts/UIxContactsListViewBase.m b/UI/Contacts/UIxContactsListViewBase.m index ddb2b425f..557074f5a 100644 --- a/UI/Contacts/UIxContactsListViewBase.m +++ b/UI/Contacts/UIxContactsListViewBase.m @@ -19,112 +19,104 @@ 02111-1307, USA. */ -#include "UIxContactsListViewBase.h" -#include -#include "common.h" +#import +#import +#import + +#import "common.h" + +#import "UIxContactsListViewBase.h" @implementation UIxContactsListViewBase -- (void)dealloc { - [self->allRecords release]; - [self->filteredRecords release]; - [self->searchText release]; - [self->contact release]; +- (void) dealloc +{ + if (searchText) + [searchText release]; [super dealloc]; } /* accessors */ -- (void)setContact:(id)_contact { - ASSIGN(self->contact, _contact); -} -- (id)contact { - return self->contact; +- (void) setCurrentContact: (id ) _contact +{ + currentContact = _contact; } -- (void)setSearchText:(NSString *)_txt { - ASSIGNCOPY(self->searchText, _txt); -} -- (id)searchText { - if (self->searchText == nil) - [self setSearchText:[[[self context] request] formValueForKey:@"search"]]; - return self->searchText; +- (id ) currentContact +{ + return currentContact; } -- (EOQualifier *)qualifier { - NSString *qs, *s; - - s = [self searchText]; - if ([s length] == 0) - return nil; - - // TODO: just use qualifier vars - qs = [NSString stringWithFormat: - @"(sn isCaseInsensitiveLike: '%@*') OR " - @"(givenname isCaseInsensitiveLike: '%@*') OR " - @"(mail isCaseInsensitiveLike: '*%@*') OR " - @"(telephonenumber isCaseInsensitiveLike: '*%@*')", - s, s, s, s]; - return [EOQualifier qualifierWithQualifierFormat:qs]; +- (void) setSearchText: (NSString *) _txt +{ + ASSIGNCOPY (searchText, _txt); } -- (NSString *)defaultSortKey { - return @"sn"; +- (id) searchText +{ + if (!searchText) + [self setSearchText: [self queryParameterForKey:@"search"]]; + + return searchText; } -- (NSString *)sortKey { + +- (NSString *) defaultSortKey +{ + return @"fn"; +} + +- (NSString *) sortKey +{ NSString *s; - s = [[[self context] request] formValueForKey:@"sort"]; - return [s length] > 0 ? s : [self defaultSortKey]; -} -- (EOSortOrdering *)sortOrdering { - SEL sel; + s = [self queryParameterForKey: @"sort"]; + if ([s length] == 0) + s = [self defaultSortKey]; - sel = [[[[self context] request] formValueForKey:@"desc"] boolValue] - ? EOCompareCaseInsensitiveDescending - : EOCompareCaseInsensitiveAscending; - - return [EOSortOrdering sortOrderingWithKey:[self sortKey] selector:sel]; -} -- (NSArray *)sortOrderings { - return [NSArray arrayWithObjects:[self sortOrdering], nil]; + return s; } -- (NSArray *)contactInfos { - // TODO: should be done in the backend, but for Agenor AB its OK here - NSArray *records; - EOQualifier *q; - - if (self->filteredRecords != nil) - return self->filteredRecords; - - records = [[self clientObject] fetchCoreInfos]; - self->allRecords = - [[records sortedArrayUsingKeyOrderArray:[self sortOrderings]] retain]; - - if ((q = [self qualifier]) != nil) { - [self debugWithFormat:@"qs: %@", q]; - self->filteredRecords = - [[self->allRecords filteredArrayUsingQualifier:q] retain]; - } - else - self->filteredRecords = [self->allRecords retain]; - - return self->filteredRecords; +- (NSComparisonResult) sortOrdering +{ + return ([[self queryParameterForKey:@"desc"] boolValue] + ? NSOrderedDescending + : NSOrderedAscending); +} + +- (NSArray *) contactInfos +{ + id folder; + + folder = [self clientObject]; + + return [folder lookupContactsWithFilter: [self searchText] + sortBy: [self sortKey] + ordering: [self sortOrdering]]; } /* notifications */ -- (void)sleep { - [self->contact release]; self->contact = nil; - [self->allRecords release]; self->allRecords = nil; - [self->filteredRecords release]; self->filteredRecords = nil; +- (void) sleep +{ + if (searchText) + { + [searchText release]; + searchText = nil; + } + currentContact = nil; +// [allRecords release]; +// allRecords = nil; +// [filteredRecords release]; +// filteredRecords = nil; [super sleep]; } /* actions */ -- (BOOL)shouldTakeValuesFromRequest:(WORequest *)_rq inContext:(WOContext*)_c{ +- (BOOL) shouldTakeValuesFromRequest: (WORequest *) _rq + inContext: (WOContext*) _c +{ return YES; } diff --git a/UI/Contacts/UIxContactsListViewContainer.h b/UI/Contacts/UIxContactsListViewContainer.h index 17df6a2b4..8d4e25980 100644 --- a/UI/Contacts/UIxContactsListViewContainer.h +++ b/UI/Contacts/UIxContactsListViewContainer.h @@ -25,7 +25,24 @@ #import +@class NSArray; +@class SOGoContactFolder; + @interface UIxContactsListViewContainer : UIxComponent +{ + NSString *foldersPrefix; + id currentFolder; +} + +- (void) setCurrentFolder: (id) folder; + +- (NSString *) foldersPrefix; + +- (NSArray *) contactFolders; + +- (NSString *) contactFolderId; +- (NSString *) currentContactFolderId; +- (NSString *) currentContactFolderName; @end diff --git a/UI/Contacts/UIxContactsListViewContainer.m b/UI/Contacts/UIxContactsListViewContainer.m index 0e026687d..2b11661f3 100644 --- a/UI/Contacts/UIxContactsListViewContainer.m +++ b/UI/Contacts/UIxContactsListViewContainer.m @@ -25,29 +25,84 @@ #import -#import +#import #import "UIxContactsListViewContainer.h" +@class SOGoContactFolders; + @implementation UIxContactsListViewContainer -- (NSString *) contactFolderName +- (id) init +{ + if ((self = [super init])) + { + foldersPrefix = nil; + } + + return self; +} + +- (void) setCurrentFolder: (id) folder +{ + currentFolder = folder; +} + +- (NSString *) foldersPrefix { NSMutableArray *folders; SOGoObject *currentObject; - folders = [NSMutableArray new]; - [folders autorelease]; - - currentObject = [self clientObject]; - while (![currentObject isKindOfClass: [SOGoContactFolders class]]) + if (!foldersPrefix) { - [folders insertObject: [currentObject nameInContainer] atIndex: 0]; - currentObject = [currentObject container]; + folders = [NSMutableArray new]; + [folders autorelease]; + + currentObject = [[self clientObject] container]; + while (![currentObject isKindOfClass: [SOGoContactFolders class]]) + { + [folders insertObject: [currentObject nameInContainer] atIndex: 0]; + currentObject = [currentObject container]; + } + + foldersPrefix = [folders componentsJoinedByString: @"/"]; + [foldersPrefix retain]; } - return [NSString stringWithFormat: @"/%@", - [folders componentsJoinedByString: @"/"]]; + return foldersPrefix; +} + +- (NSString *) contactFolderId +{ + return [NSString stringWithFormat: @"%@/%@", + [self foldersPrefix], + [[self clientObject] nameInContainer]]; +} + +- (NSArray *) contactFolders +{ + SOGoContactFolders *folderContainer; + + folderContainer = [[self clientObject] container]; + + return [folderContainer contactFolders]; +} + +- (NSString *) currentContactFolderId +{ + return [NSString stringWithFormat: @"%@/%@", + [self foldersPrefix], + [currentFolder nameInContainer]]; +} + +- (NSString *) currentContactFolderName +{ + return [self labelForKey: [currentFolder displayName]]; +} + +- (BOOL) isFolderCurrent +{ + return [[self currentContactFolderId] isEqualToString: [self contactFolderId]]; } @end diff --git a/UI/Contacts/product.plist b/UI/Contacts/product.plist index 3bde67be8..9981bc000 100644 --- a/UI/Contacts/product.plist +++ b/UI/Contacts/product.plist @@ -17,7 +17,7 @@ }; }; - SOGoContactFolder = { + SOGoContactGCSFolder = { slots = { toolbar = { protectedBy = "View"; @@ -41,13 +41,59 @@ }; }; - SOGoContactObject = { + SOGoContactLDAPFolder = { slots = { toolbar = { protectedBy = "View"; - value = "SOGoContactObject.toolbar"; + value = "SOGoContactFolder.toolbar"; }; }; + methods = { + view = { + protectedBy = "View"; + pageName = "UIxContactsListView"; + }; + new = { + protectedBy = "View"; + pageName = "UIxContactEditor"; + actionName = "new"; + }; + select = { + protectedBy = "View"; + pageName = "UIxContactsSelectionView"; + }; + }; + }; + + SOGoContactGCSEntry = { + methods = { + view = { + protectedBy = "View"; + pageName = "UIxContactView"; + }; + delete = { + protectedBy = "View"; + pageName = "UIxContactView"; + actionName = "delete"; + }; + edit = { + protectedBy = "View"; + pageName = "UIxContactEditor"; + }; + save = { + protectedBy = "View"; + pageName = "UIxContactEditor"; + actionName = "save"; + }; + write = { + protectedBy = "View"; + pageName = "UIxContactEditor"; + actionName = "write"; + }; + }; + }; + + SOGoContactLDAPEntry = { methods = { view = { protectedBy = "View";