From c96c7897db0b35b422d0db613aba29bdaaf8183e Mon Sep 17 00:00:00 2001 From: wolfgang Date: Thu, 18 Oct 2007 22:55:51 +0000 Subject: [PATCH] git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1188 d1b88da0-ebda-0310-925b-ed51d893ca5b --- ChangeLog | 77 + NEWS | 5 + SoObjects/Contacts/SOGoContactGCSFolder.m | 60 +- SoObjects/Mailer/SOGoMailAccount.m | 44 +- SoObjects/Mailer/SOGoMailFolder.m | 8 +- SoObjects/Mailer/SOGoMailObject.h | 2 + SoObjects/Mailer/SOGoMailObject.m | 30 +- SoObjects/SOGo/SOGoFolder.m | 31 +- SoObjects/SOGo/SOGoUser.h | 6 + SoObjects/SOGo/SOGoUser.m | 21 + SoObjects/SOGo/SOGoWebAuthenticator.m | 17 + UI/Common/English.lproj/Localizable.strings | 2 + UI/Common/French.lproj/Localizable.strings | 2 + UI/Common/German.lproj/Localizable.strings | 2 + UI/Common/UIxAclEditor.h | 1 + UI/Common/UIxAclEditor.m | 9 + UI/Common/UIxPageFrame.h | 11 +- UI/Common/UIxPageFrame.m | 90 +- UI/MailerUI/English.lproj/Localizable.strings | 71 +- UI/MailerUI/French.lproj/Localizable.strings | 16 + UI/MailerUI/German.lproj/Localizable.strings | 16 + UI/MailerUI/UIxMailActions.m | 22 +- UI/MailerUI/UIxMailFolderActions.m | 52 + UI/MailerUI/product.plist | 20 + UI/MainUI/SOGoRootPage.m | 2 +- UI/SOGoUI/GNUmakefile | 4 +- UI/SOGoUI/SOGoACLAdvisory.h | 24 +- UI/SOGoUI/SOGoACLAdvisory.m | 25 +- UI/SOGoUI/SOGoFolderAdvisory.h | 68 + UI/SOGoUI/SOGoFolderAdvisory.m | 232 +++ UI/Scheduler/UIxAppointmentEditor.m | 90 +- UI/Templates/ContactsUI/UIxContactEditor.wox | 4 - .../ContactsUI/UIxContactsUserFolders.wox | 7 +- UI/Templates/MailerUI/UIxMailEditor.wox | 3 +- UI/Templates/MailerUI/UIxMailMainFrame.wox | 15 +- UI/Templates/MailerUI/UIxMailToSelection.wox | 1 - UI/Templates/MailerUI/UIxMailTree.wox | 39 - UI/Templates/MailerUI/UIxMailTreeBlockJS.wox | 7 - .../SOGoFolderEnglishAdditionAdvisory.wox | 22 + .../SOGoFolderEnglishRemovalAdvisory.wox | 22 + .../SOGoFolderFrenchAdditionAdvisory.wox | 21 + .../SOGoFolderFrenchRemovalAdvisory.wox | 22 + .../SOGoFolderGermanAdditionAdvisory.wox | 22 + .../SOGoFolderGermanRemovalAdvisory.wox | 22 + .../SchedulerUI/UIxAttendeesEditor.wox | 4 +- UI/Templates/SchedulerUI/UIxCalMainView.wox | 3 +- .../SchedulerUI/UIxComponentEditor.wox | 5 +- UI/Templates/UIxAclEditor.wox | 6 +- UI/Templates/UIxPageFrame.wox | 148 +- UI/WebServerResources/ContactsUI.js | 16 +- UI/WebServerResources/HTMLElement.js | 7 +- .../JavascriptAPIExtensions.js | 18 + UI/WebServerResources/MailerUI+dTree.js | 9 +- UI/WebServerResources/MailerUI.js | 163 +- UI/WebServerResources/SchedulerUI.js | 2 +- UI/WebServerResources/UIxContactEditor.js | 6 +- UI/WebServerResources/UIxMailEditor.css | 2 +- UI/WebServerResources/UIxMailEditor.js | 21 +- UI/WebServerResources/generic.css | 2 +- UI/WebServerResources/generic.js | 796 ++++---- UI/WebServerResources/tablekit.js | 1716 ++++++++--------- UI/WebServerResources/tbtv_sent_17x17.gif | Bin 654 -> 628 bytes 62 files changed, 2573 insertions(+), 1618 deletions(-) create mode 100644 UI/SOGoUI/SOGoFolderAdvisory.h create mode 100644 UI/SOGoUI/SOGoFolderAdvisory.m delete mode 100644 UI/Templates/MailerUI/UIxMailTree.wox delete mode 100644 UI/Templates/MailerUI/UIxMailTreeBlockJS.wox create mode 100644 UI/Templates/SOGoFolderEnglishAdditionAdvisory.wox create mode 100644 UI/Templates/SOGoFolderEnglishRemovalAdvisory.wox create mode 100644 UI/Templates/SOGoFolderFrenchAdditionAdvisory.wox create mode 100644 UI/Templates/SOGoFolderFrenchRemovalAdvisory.wox create mode 100644 UI/Templates/SOGoFolderGermanAdditionAdvisory.wox create mode 100644 UI/Templates/SOGoFolderGermanRemovalAdvisory.wox diff --git a/ChangeLog b/ChangeLog index 1c09f87e..82b63675 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,80 @@ +2007-10-18 Wolfgang Sourdeau + + * SoObjects/SOGo/SOGoWebAuthenticator.m ([SOGoWebAuthenticator + -userInContext:]): override the super method by returning + anonymous if the super returns nil. + + * UI/Common/UIxPageFrame.m ([UIxPageFrame + -productLocalizableStrings]): new method that returns the + product-specific translation dictionary as a JSON hash. + ([UIxPageFrame -commonLocalizableStrings]): same as above but for + the "Common" framework. + ([UIxPageFrame -setJsFiles:newJSFiles]): new setter that enables + the requestor components to require additional Javascript files. + This is useful now that all the scripts are loaded at the end of + the HTML code. + ([UIxPageFrame -additionalJSFiles]): new getter related to the + above. + +2007-10-17 Wolfgang Sourdeau + + * UI/MailerUI/UIxMailActions.m ([UIxMailActions -copyAction]): + implemented new web method. + + * SoObjects/Mailer/SOGoMailObject.m ([SOGoMailObject + -copyToFolderNamed:folderNameinContext:]): new method with the + code cut/pasted from -moveToFolderNamed:inContext:. + ([SOGoMailObject -moveToFolderNamed:folderNameinContext:]): + modified to use the code from -copyToFolderNamed:inContext:, which + is common between the two actions. + + * SoObjects/Mailer/SOGoMailAccount.m ([SOGoMailAccount -draftsFolderNameInContext:_ctx]) + ([SOGoMailAccount -sentFolderNameInContext:]) + ([SOGoMailAccount -trashFolderNameInContext:]): modified to take + the user settings into account. + + * UI/MailerUI/UIxMailFolderActions.m ([UIxMailFolderActions -setAsDraftsFolderAction]) + ([UIxMailFolderActions -setAsSentFolderAction]) + ([UIxMailFolderActions -setAsTrashFolderAction]): new web methods + that change the purpose of the active folder to "Sent", "Drafts" + or "Trash". + + * UI/SOGoUI/SOGoACLAdvisory.m ([SOGoACLAdvisory -subject]): + returns the subject as quoted-printable. + + * UI/SOGoUI/SOGoACLAdvisory.[hm]: added two intermediary classes: + SOGoACLAdditionAdvisory and SOGoACLRemovalAdvisory implementing + the "aclMethod" method for the subsequent language-dependent + subclasses. + + * UI/SOGoUI/SOGoFolderAdvisory.m ([SOGoFolderAdvisory -subject]): + returns the subject as quoted-printable. + + * UI/Scheduler/UIxAppointmentEditor.m ([UIxAppointmentEditor + -dealloc]): release item, aptStartDate and aptEndDate. + +2007-10-16 Wolfgang Sourdeau + + * SoObjects/Mailer/SOGoMailFolder.m ([SOGoMailFolder + -initWithName:newNameinContainer:newContainer]): the owner of a + shared folder is set to "nobody" by default. + + * UI/Common/UIxAclEditor.m ([UIxAclEditor -hasOwner]): new method + that returns whether the object has an owner or not. + +2007-10-15 Wolfgang Sourdeau + + * SoObjects/SOGo/SOGoFolder.m ([SOGoFolder -ocsFolder]): create + the folder even if the current user is not its owner. + +2007-10-10 Ludovic Marcotte + + * We now send advisory emails when folders + are created / deleted. + + * Fixed the sending of advisory emails upon + ACL changes on folders. + 2007-10-10 Ludovic Marcotte * UI/Scheduler/UIxComponentEditor.m diff --git a/NEWS b/NEWS index a61bbec9..95e1bff6 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,8 @@ +0.9.0-200710XX +-------------- +- the user can now configure his folders as drafts, trash or sent folder; +- added the ability the move and copy message across mail folders; + 0.9.0-200709XX -------------- - implemented cookie-based identification in the web interface; diff --git a/SoObjects/Contacts/SOGoContactGCSFolder.m b/SoObjects/Contacts/SOGoContactGCSFolder.m index 1a58723d..26e0e974 100644 --- a/SoObjects/Contacts/SOGoContactGCSFolder.m +++ b/SoObjects/Contacts/SOGoContactGCSFolder.m @@ -25,8 +25,10 @@ #import #import #import +#import #import #import +#import #import #import #import @@ -103,7 +105,6 @@ if (filter && [filter length] > 0) { -#warning why we do not use %%%@%% everywhere? qs = [NSString stringWithFormat: @"(c_sn isCaseInsensitiveLike: '%@%%') OR " @"(c_givenname isCaseInsensitiveLike: '%@%%') OR " @@ -195,7 +196,6 @@ NSMutableDictionary *filterData; id parentNode; id ranges; - NSString *componentName; parentNode = [filterElement parentNode]; @@ -244,34 +244,6 @@ return filters; } -- (void) _appendComponentsMatchingFilters: (NSArray *) filters - toResponse: (WOResponse *) response -{ - unsigned int count, max; - NSDictionary *currentFilter, *contact; - NSEnumerator *contacts; - NSString *baseURL; - - baseURL = [self baseURLInContext: context]; - - max = [filters count]; - for (count = 0; count < max; count++) - { - currentFilter = [filters objectAtIndex: count]; - contacts = [[self lookupContactsWithFilter: [[currentFilter allValues] lastObject] - sortBy: @"c_givenname" - ordering: NSOrderedDescending] - objectEnumerator]; - - while ((contact = [contacts nextObject])) - { - [self appendObject: contact - withBaseURL: baseURL - toREPORTResponse: response]; - } - } -} - - (void) appendObject: (NSDictionary *) object withBaseURL: (NSString *) baseURL toREPORTResponse: (WOResponse *) r @@ -308,6 +280,34 @@ [r appendContentString: @" \r\n"]; } +- (void) _appendComponentsMatchingFilters: (NSArray *) filters + toResponse: (WOResponse *) response +{ + unsigned int count, max; + NSDictionary *currentFilter, *contact; + NSEnumerator *contacts; + NSString *baseURL; + + baseURL = [self baseURLInContext: context]; + + max = [filters count]; + for (count = 0; count < max; count++) + { + currentFilter = [filters objectAtIndex: count]; + contacts = [[self lookupContactsWithFilter: [[currentFilter allValues] lastObject] + sortBy: @"c_givenname" + ordering: NSOrderedDescending] + objectEnumerator]; + + while ((contact = [contacts nextObject])) + { + [self appendObject: contact + withBaseURL: baseURL + toREPORTResponse: response]; + } + } +} + - (NSArray *) lookupContactsWithFilter: (NSString *) filter sortBy: (NSString *) sortKey ordering: (NSComparisonResult) sortOrdering diff --git a/SoObjects/Mailer/SOGoMailAccount.m b/SoObjects/Mailer/SOGoMailAccount.m index bf2a7a58..eea913c2 100644 --- a/SoObjects/Mailer/SOGoMailAccount.m +++ b/SoObjects/Mailer/SOGoMailAccount.m @@ -32,6 +32,8 @@ #import #import +#import + #import "SOGoMailFolder.h" #import "SOGoMailManager.h" #import "SOGoDraftsFolder.h" @@ -333,10 +335,32 @@ static BOOL useAltNamespace = NO; return [NSString stringWithFormat: @"folder%@", inboxFolderName]; } +- (NSString *) _userFolderNameWithPurpose: (NSString *) purpose +{ + NSUserDefaults *ud; + NSMutableDictionary *mailSettings; + NSString *folderName; + + folderName = nil; + ud = [[context activeUser] userSettings]; + mailSettings = [ud objectForKey: @"Mail"]; + if (mailSettings) + folderName + = [mailSettings objectForKey: [NSString stringWithFormat: @"%@Folder", + purpose]]; + + return folderName; +} + - (NSString *) draftsFolderNameInContext: (id) _ctx { - /* SOGo managed folder */ - return [NSString stringWithFormat: @"folder%@", draftsFolderName]; + NSString *folderName; + + folderName = [self _userFolderNameWithPurpose: @"Drafts"]; + if (!folderName) + folderName = draftsFolderName; + + return [NSString stringWithFormat: @"folder%@", folderName]; } - (NSString *) sieveFolderNameInContext: (id) _ctx @@ -346,12 +370,24 @@ static BOOL useAltNamespace = NO; - (NSString *) sentFolderNameInContext: (id)_ctx { - return [NSString stringWithFormat: @"folder%@", sentFolderName]; + NSString *folderName; + + folderName = [self _userFolderNameWithPurpose: @"Sent"]; + if (!folderName) + folderName = sentFolderName; + + return [NSString stringWithFormat: @"folder%@", folderName]; } - (NSString *) trashFolderNameInContext: (id)_ctx { - return [NSString stringWithFormat: @"folder%@", trashFolderName]; + NSString *folderName; + + folderName = [self _userFolderNameWithPurpose: @"Trash"]; + if (!folderName) + folderName = trashFolderName; + + return [NSString stringWithFormat: @"folder%@", folderName]; } - (SOGoMailFolder *) inboxFolderInContext: (id) _ctx diff --git a/SoObjects/Mailer/SOGoMailFolder.m b/SoObjects/Mailer/SOGoMailFolder.m index babd5684..892a663c 100644 --- a/SoObjects/Mailer/SOGoMailFolder.m +++ b/SoObjects/Mailer/SOGoMailFolder.m @@ -63,7 +63,7 @@ static BOOL useAltNamespace = NO; folder = [mailAccount sharedFolderName]; if (folder && [path hasPrefix: folder]) - [self setOwner: @"anyone"]; + [self setOwner: @"nobody"]; else { folder = [mailAccount otherUsersFolderName]; @@ -73,7 +73,7 @@ static BOOL useAltNamespace = NO; if ([names count] > 1) [self setOwner: [names objectAtIndex: 1]]; else - [self setOwner: @"anyone"]; + [self setOwner: @"nobody"]; } } } @@ -585,7 +585,7 @@ static BOOL useAltNamespace = NO; return userPath; } -- (NSString *) httpURLForAdvisoryToUser: (NSString *) uid; +- (NSString *) httpURLForAdvisoryToUser: (NSString *) uid { SOGoUser *user; NSString *otherUsersPath, *url; @@ -609,7 +609,7 @@ static BOOL useAltNamespace = NO; return url; } -- (NSString *) resourceURLForAdvisoryToUser: (NSString *) uid; +- (NSString *) resourceURLForAdvisoryToUser: (NSString *) uid { NSURL *selfURL, *userURL; diff --git a/SoObjects/Mailer/SOGoMailObject.h b/SoObjects/Mailer/SOGoMailObject.h index c81e4103..80e09538 100644 --- a/SoObjects/Mailer/SOGoMailObject.h +++ b/SoObjects/Mailer/SOGoMailObject.h @@ -89,6 +89,8 @@ - (BOOL)isDeletionAllowed; - (NSException *) trashInContext:(id)_ctx; +- (NSException *) copyToFolderNamed: (NSString *) folderName + inContext: (id)_ctx; - (NSException *) moveToFolderNamed: (NSString *) folderName inContext: (id)_ctx; diff --git a/SoObjects/Mailer/SOGoMailObject.m b/SoObjects/Mailer/SOGoMailObject.m index c0b4929f..cd2e8d48 100644 --- a/SoObjects/Mailer/SOGoMailObject.m +++ b/SoObjects/Mailer/SOGoMailObject.m @@ -888,13 +888,12 @@ static BOOL debugSoParts = NO; return nil; } -- (NSException *) moveToFolderNamed: (NSString *) folderName +- (NSException *) copyToFolderNamed: (NSString *) folderName inContext: (id)_ctx { SOGoMailAccounts *destFolder; NSEnumerator *folders; NSString *currentFolderName, *reason; - NSException *error; // TODO: check for safe HTTP method @@ -924,18 +923,27 @@ static BOOL debugSoParts = NO; [destFolder flushMailCaches]; /* a) copy */ - - error = [self davCopyToTargetObject: destFolder - newName: @"fakeNewUnusedByIMAP4" /* autoassigned */ - inContext:_ctx]; - if (error != nil) return error; - /* b) mark deleted */ + return [self davCopyToTargetObject: destFolder + newName: @"fakeNewUnusedByIMAP4" /* autoassigned */ + inContext:_ctx]; +} + +- (NSException *) moveToFolderNamed: (NSString *) folderName + inContext: (id)_ctx +{ + NSException *error; + + if (![self copyToFolderNamed: folderName + inContext: _ctx]) + { + /* b) mark deleted */ - error = [[self imap4Connection] markURLDeleted: [self imap4URL]]; - if (error != nil) return error; + error = [[self imap4Connection] markURLDeleted: [self imap4URL]]; + if (error != nil) return error; - [self flushMailCaches]; + [self flushMailCaches]; + } return nil; } diff --git a/SoObjects/SOGo/SOGoFolder.m b/SoObjects/SOGo/SOGoFolder.m index db7256ef..28697447 100644 --- a/SoObjects/SOGo/SOGoFolder.m +++ b/SoObjects/SOGo/SOGoFolder.m @@ -31,6 +31,7 @@ #import #import #import +#import #import #import #import @@ -41,6 +42,7 @@ #import #import #import +#import #import "NSArray+Utilities.h" #import "NSString+Utilities.h" @@ -235,7 +237,7 @@ static NSString *defaultUserID = @""; ocsFolder = [self ocsFolderForPath: [self ocsPath]]; userLogin = [[context activeUser] login]; if (!ocsFolder - && [userLogin isEqualToString: [self ownerInContext: context]] +/* && [userLogin isEqualToString: [self ownerInContext: context]] */ && [self folderIsMandatory] && [self create]) ocsFolder = [self ocsFolderForPath: [self ocsPath]]; @@ -255,15 +257,35 @@ static NSString *defaultUserID = @""; return @""; } +- (void) sendFolderAdvisoryTemplate: (NSString *) template +{ + NSString *language, *pageName; + SOGoUser *user; + SOGoFolderAdvisory *page; + WOApplication *app; + + user = [SOGoUser userWithLogin: [[context activeUser] login] roles: nil]; + language = [user language]; + pageName = [NSString stringWithFormat: @"SOGoFolder%@%@Advisory", + language, template]; + + app = [WOApplication application]; + page = [app pageWithName: pageName inContext: context]; + [page setFolderObject: self]; + [page setRecipientUID: [[context activeUser] login]]; + [page send]; +} + - (BOOL) create { NSException *result; -// [self dieHard]; result = [[self folderManager] createFolderOfType: [self folderType] withName: displayName atPath: ocsPath]; + if (!result) [self sendFolderAdvisoryTemplate: @"Addition"]; + return (result == nil); } @@ -271,12 +293,17 @@ static NSString *defaultUserID = @""; { NSException *error; + // We just fetch our displayName since our table will use it! + [self displayName]; + if ([nameInContainer isEqualToString: @"personal"]) error = [NSException exceptionWithHTTPStatus: 403 reason: @"folder 'personal' cannot be deleted"]; else error = [[self folderManager] deleteFolderAtPath: ocsPath]; + if (!error) [self sendFolderAdvisoryTemplate: @"Removal"]; + return error; } diff --git a/SoObjects/SOGo/SOGoUser.h b/SoObjects/SOGo/SOGoUser.h index 335e371e..97711c56 100644 --- a/SoObjects/SOGo/SOGoUser.h +++ b/SoObjects/SOGo/SOGoUser.h @@ -48,6 +48,12 @@ extern NSString *SOGoWeekStartJanuary1; extern NSString *SOGoWeekStartFirst4DayWeek; extern NSString *SOGoWeekStartFirstFullWeek; +@interface SoUser (SOGoExtension) + +- (NSString *) language; + +@end + @interface SOGoUser : SoUser { NSString *currentPassword; diff --git a/SoObjects/SOGo/SOGoUser.m b/SoObjects/SOGo/SOGoUser.m index 0197ca93..9cd0c562 100644 --- a/SoObjects/SOGo/SOGoUser.m +++ b/SoObjects/SOGo/SOGoUser.m @@ -57,6 +57,27 @@ NSString *SOGoWeekStartFirstFullWeek = @"FirstFullWeek"; @end +@implementation SoUser (SOGoExtension) + +- (NSString *) language +{ + NSArray *bLanguages; + WOContext *context; + NSString *language; + + context = [[WOApplication application] context]; + bLanguages = [[context request] browserLanguages]; + if ([bLanguages count] > 0) + language = [bLanguages objectAtIndex: 0]; + + if (![language length]) + language = defaultLanguage; + + return language; +} + +@end + @implementation SOGoUser + (void) initialize diff --git a/SoObjects/SOGo/SOGoWebAuthenticator.m b/SoObjects/SOGo/SOGoWebAuthenticator.m index 36a96282..68c80259 100644 --- a/SoObjects/SOGo/SOGoWebAuthenticator.m +++ b/SoObjects/SOGo/SOGoWebAuthenticator.m @@ -92,6 +92,23 @@ // && [_pwd isEqualToString: @"freebusy"])); } +- (SOGoUser *) userInContext: (WOContext *)_ctx +{ + static SOGoUser *anonymous = nil; + SOGoUser *user; + + if (!anonymous) + anonymous + = [[SOGoUser alloc] initWithLogin: @"anonymous" + roles: [NSArray arrayWithObject: SoRole_Anonymous]]; + + user = (SOGoUser *) [super userInContext: _ctx]; + if (!user) + user = anonymous; + + return user; +} + - (NSString *) passwordInContext: (WOContext *) context { NSArray *creds; diff --git a/UI/Common/English.lproj/Localizable.strings b/UI/Common/English.lproj/Localizable.strings index dec4c8c7..1ae7857e 100644 --- a/UI/Common/English.lproj/Localizable.strings +++ b/UI/Common/English.lproj/Localizable.strings @@ -44,3 +44,5 @@ "Unable to rename that folder!" = "Unable to rename that folder!"; "You have already subscribed to that folder!" = "You have already subscribed to that folder!"; +"The user rights cannot be edited for this object!" + = "The user rights cannot be edited for this object!"; diff --git a/UI/Common/French.lproj/Localizable.strings b/UI/Common/French.lproj/Localizable.strings index 5e1e6ce0..2de07b5c 100644 --- a/UI/Common/French.lproj/Localizable.strings +++ b/UI/Common/French.lproj/Localizable.strings @@ -41,3 +41,5 @@ "Unable to rename that folder!" = "Impossible de renommer ce dossier."; "You have already subscribed to that folder!" = "Vous êtes déja abonné à ce dossier."; +"The user rights cannot be edited for this object!" + = "Les droits sur cet objet ne peuvent pas être édités."; diff --git a/UI/Common/German.lproj/Localizable.strings b/UI/Common/German.lproj/Localizable.strings index a7feaba3..68e8862e 100644 --- a/UI/Common/German.lproj/Localizable.strings +++ b/UI/Common/German.lproj/Localizable.strings @@ -38,3 +38,5 @@ "Unable to rename that folder!" = "Unable to rename that folder!"; "You have already subscribed to that folder!" = "You have already subscribed to that folder!"; +"The user rights cannot be edited for this object!" + = "The user rights cannot be edited for this object!"; diff --git a/UI/Common/UIxAclEditor.h b/UI/Common/UIxAclEditor.h index f8104cee..41f418e7 100644 --- a/UI/Common/UIxAclEditor.h +++ b/UI/Common/UIxAclEditor.h @@ -43,6 +43,7 @@ - (NSString *) currentUser; - (NSString *) ownerName; +- (BOOL) hasOwner; @end diff --git a/UI/Common/UIxAclEditor.m b/UI/Common/UIxAclEditor.m index e6dccdfe..123bd496 100644 --- a/UI/Common/UIxAclEditor.m +++ b/UI/Common/UIxAclEditor.m @@ -87,6 +87,15 @@ return [self _displayNameForUID: ownerLogin]; } +- (BOOL) hasOwner +{ + NSString *ownerLogin; + + ownerLogin = [[self clientObject] ownerInContext: context]; + + return (![ownerLogin isEqualToString: @"nobody"]); +} + - (NSString *) defaultUserID { if (!defaultUserID) diff --git a/UI/Common/UIxPageFrame.h b/UI/Common/UIxPageFrame.h index 1faf08cb..1c3094a5 100644 --- a/UI/Common/UIxPageFrame.h +++ b/UI/Common/UIxPageFrame.h @@ -25,6 +25,9 @@ #import #import +@class NSString; +@class NSMutableArray; + @interface WOComponent (PopupExtension) - (BOOL) isPopup; @@ -37,20 +40,24 @@ NSString *toolbar; id item; BOOL isPopup; + NSMutableArray *additionalJSFiles; } +- (NSString *) commonLocalizableStrings; +- (NSString *) productLocalizableStrings; + - (NSString *) pageJavaScriptURL; - (NSString *) productJavaScriptURL; - (BOOL) hasPageSpecificJavaScript; - (BOOL) hasProductSpecificJavaScript; +- (NSArray *) additionalJSFiles; + - (NSString *) pageCSSURL; - (NSString *) productCSSURL; - (BOOL) hasPageSpecificCSS; - (BOOL) hasProductSpecificCSS; -- (NSString *) productFrameworkName; - - (void) setPopup: (BOOL) popup; - (BOOL) isPopup; diff --git a/UI/Common/UIxPageFrame.m b/UI/Common/UIxPageFrame.m index a5e6989a..447572b0 100644 --- a/UI/Common/UIxPageFrame.m +++ b/UI/Common/UIxPageFrame.m @@ -23,8 +23,10 @@ #import #import +#import +#import + #import -#import #import
@@ -36,7 +38,10 @@ { if ((self = [super init])) { + item = nil; + title = nil; toolbar = nil; + additionalJSFiles = nil; } return self; @@ -46,8 +51,8 @@ { [item release]; [title release]; - if (toolbar) - [toolbar release]; + [toolbar release]; + [additionalJSFiles release]; [super dealloc]; } @@ -55,7 +60,7 @@ - (void) setTitle: (NSString *) _value { - ASSIGNCOPY(title, _value); + ASSIGN (title, _value); } - (NSString *) title @@ -68,7 +73,7 @@ - (void) setItem: (id) _item { - ASSIGN(item, _item); + ASSIGN (item, _item); } - (id) item @@ -166,6 +171,39 @@ /* page based JavaScript */ +- (NSString *) _stringsForFramework: (NSString *) framework +{ + NSString *language, *frameworkName; + id table; + + frameworkName = [NSString stringWithFormat: @"%@.SOGo", + (framework ? framework : [self frameworkName])]; + language = [[context activeUser] language]; + table + = [[self resourceManager] stringTableWithName: @"Localizable" + inFramework: frameworkName + languages: [NSArray arrayWithObject: language]]; + + /* table is not really an NSDictionary but a hackish variation thereof */ + return [[NSDictionary dictionaryWithDictionary: table] jsonRepresentation]; +} + +- (NSString *) commonLocalizableStrings +{ + return [NSString stringWithFormat: @"var clabels = %@;", + [self _stringsForFramework: nil]]; +} + +- (NSString *) productLocalizableStrings +{ + NSString *frameworkName; + + frameworkName = [[context page] frameworkName]; + + return [NSString stringWithFormat: @"var labels = %@;", + [self _stringsForFramework: frameworkName]]; +} + - (NSString *) pageJavaScriptURL { WOComponent *page; @@ -190,15 +228,6 @@ return [self urlForResourceFilename: fwJSFilename]; } -- (NSString *) productFrameworkName -{ - WOComponent *page; - - page = [context page]; - - return [NSString stringWithFormat: @"%@.SOGo", [page frameworkName]]; -} - - (BOOL) hasPageSpecificJavaScript { return ([[self pageJavaScriptURL] length] > 0); @@ -209,6 +238,28 @@ return ([[self productJavaScriptURL] length] > 0); } +- (void) setJsFiles: (NSString *) newJSFiles +{ + NSEnumerator *jsFiles; + NSString *currentFile, *filename; + + [additionalJSFiles release]; + additionalJSFiles = [NSMutableArray new]; + + jsFiles = [[newJSFiles componentsSeparatedByString: @","] objectEnumerator]; + while ((currentFile = [jsFiles nextObject])) + { + filename = [self urlForResourceFilename: + [currentFile stringByTrimmingSpaces]]; + [additionalJSFiles addObject: filename]; + } +} + +- (NSArray *) additionalJSFiles +{ + return additionalJSFiles; +} + - (NSString *) pageCSSURL { WOComponent *page; @@ -270,10 +321,12 @@ NSLog(@"User agent = %@", [cc userAgent]); //NSLog(@"Browser major version = %i", [cc majorVersion]); - return ( - ([[cc userAgentType] isEqualToString: @"IE"] && [cc majorVersion] >= 7) || - ([[cc userAgentType] isEqualToString: @"Mozilla"] && [cc majorVersion] >= 5) || - ([[cc userAgentType] isEqualToString: @"Safari"] && [cc majorVersion] >= 4) + return (([[cc userAgentType] isEqualToString: @"IE"] + && [cc majorVersion] >= 7) + || ([[cc userAgentType] isEqualToString: @"Mozilla"] + && [cc majorVersion] >= 5) + || ([[cc userAgentType] isEqualToString: @"Safari"] + && [cc majorVersion] >= 4) // ([[cc userAgentType] isEqualToString: @"Konqueror"]) ); } @@ -298,5 +351,4 @@ return [cc isMacBrowser]; } - @end /* UIxPageFrame */ diff --git a/UI/MailerUI/English.lproj/Localizable.strings b/UI/MailerUI/English.lproj/Localizable.strings index b8d4e8b9..cf14bf58 100644 --- a/UI/MailerUI/English.lproj/Localizable.strings +++ b/UI/MailerUI/English.lproj/Localizable.strings @@ -139,9 +139,66 @@ "MoveTo" = "Move …"; -"error_missingsubject" = "Missing Subject"; -"error_missingrecipients" = "Missing Recipients"; -"error_validationfailed" = "Validation failed"; +/* Address Popup menu */ +"Add to Address Book..." = "Add to Address Book..."; +"Compose Mail To" = "Compose Mail To"; +"Create Filter From Message..." = "Create Filter From Message..."; + +/* Mailbox popup menus */ +"Open in New Mail Window" = "Open in New Mail Window"; +"Copy Folder Location" = "Copy Folder Location"; +"Subscribe..." = "Subscribe..."; +"Mark Folder Read..." = "Mark Folder Read..."; +"New Folder..." = "New Folder..."; +"Compact This Folder" = "Compact This Folder"; +"Search Messages..." = "Search Messages..."; +"Sharing..." = "Sharing..."; +"New Subfolder..." = "New Subfolder..."; +"Rename Folder..." = "Rename Folder..."; +"Delete Folder" = "Delete Folder"; +"Use This Folder For" = "Use This Folder For"; +"Get Messages for Account" = "Get Messages for Account"; + +/* Use This Folder menu */ +"Sent Messages" = "Sent Messages"; +"Drafts" = "Drafts"; +"Deleted Messages" = "Deleted Messages"; + +/* Message list popup menu */ +"Open Message In New Window" = "Open Message In New Window"; +"Reply to Sender Only" = "Reply to Sender Only"; +"Reply to All" = "Reply to All"; +"Forward" = "Forward"; +"Edit As New..." = "Edit As New..."; +"Move To" = "Move To"; +"Copy To" = "Copy To"; +"Label" = "Label"; +"Mark" = "Mark"; +"Save As..." = "Save As..."; +"Print Preview" = "Print Preview"; +"View Message Source" = "View Message Source"; +"Print..." = "Print..."; +"Delete Message" = "Delete Message"; + +"This Folder" = "This Folder"; + +/* Label popup menu */ +"None" = "None"; +"Important" = "Important"; +"Work" = "Work"; +"Personal" = "Personal"; +"To Do" = "To Do"; +"Later" = "Later"; + +/* Mark popup menu */ +"As Read" = "As Read"; +"Thread As Read" = "Thread As Read"; +"As Read By Date..." = "As Read By Date..."; +"All Read" = "All Read"; +"Flag" = "Flag"; +"As Junk" = "As Junk"; +"As Not Junk" = "As Not Junk"; +"Run Junk Mail Controls" = "Run Junk Mail Controls"; /* Folder operations */ "Name :" = "Name :"; @@ -156,3 +213,11 @@ "Please select a message." = "Please select a message."; "Please select a message to print." = "Please select a message to print."; "Please select only one message to print." = "Please select only one message to print."; + +"You need to choose a non-virtual folder!" = "You need to choose a non-virtual folder!"; +"You need to choose a root subfolder!" = "You need to choose a root subfolder!"; + +"Moving a message into its own folder is impossible!" += "Moving a message into its own folder is impossible!"; +"Copying a message into its own folder is impossible!" += "Copying a message into its own folder is impossible!"; diff --git a/UI/MailerUI/French.lproj/Localizable.strings b/UI/MailerUI/French.lproj/Localizable.strings index 3fed423b..b68ab6bb 100644 --- a/UI/MailerUI/French.lproj/Localizable.strings +++ b/UI/MailerUI/French.lproj/Localizable.strings @@ -157,8 +157,14 @@ "New Subfolder..." = "Nouveau sous-dossier..."; "Rename Folder..." = "Renommer le dossier..."; "Delete Folder" = "Supprimer le dossier..."; +"Use This Folder For" = "Utiliser ce dossier pour"; "Get Messages for Account" = "Relever les messages de ce compte"; +/* Use This Folder menu */ +"Sent Messages" = "les message envoyés"; +"Drafts" = "les brouillons"; +"Deleted Messages" = "les message effacés"; + /* Message list popup menu */ "Open Message In New Window" = "Ouvrir dans une nouvelle fenétre"; "Reply to Sender Only" = "Répondre à l'expéditeur"; @@ -175,6 +181,8 @@ "Print..." = "Imprimer..."; "Delete Message" = "Supprimer le message"; +"This Folder" = "Ce dossier-ci"; + /* Label popup menu */ "None" = "Aucune"; "Important" = "Important"; @@ -206,3 +214,11 @@ "Please select a message." = "Veuillez sélectionner un message."; "Please select a message to print." = "Veuillez sélectionner un message à imprimer."; "Please select only one message to print." = "Veuillez ne sélectionner qu'un seul message à imprimer."; + +"You need to choose a non-virtual folder!" = "Vous devez choisir un dossier non-virtuel."; +"You need to choose a root subfolder!" = "Vous devez choisir un sous-dossier de la racine."; + +"Moving a message into its own folder is impossible!" += "Le déplacement d'un message dans son propre dossier est impossible."; +"Copying a message into its own folder is impossible!" += "La copie d'un message dans son propre dossier est impossible."; diff --git a/UI/MailerUI/German.lproj/Localizable.strings b/UI/MailerUI/German.lproj/Localizable.strings index ad9ec372..31b91fe6 100644 --- a/UI/MailerUI/German.lproj/Localizable.strings +++ b/UI/MailerUI/German.lproj/Localizable.strings @@ -140,8 +140,14 @@ "New Subfolder..." = "Neuer Unterordner..."; "Rename Folder..." = "Umbenennen..."; "Delete Folder" = "Löschen"; +"Use This Folder For" = "Use This Folder For"; "Get Messages for Account" = "Neue Nachrichten empfangen"; +/* Use This Folder menu */ +"Sent Messages" = "Sent Messages"; +"Drafts" = "Drafts"; +"Deleted Messages" = "Deleted Messages"; + /* Message list popup menu */ "Open Message In New Window" = "In neuem Fenster õffnen"; "Reply to Sender Only" = "Antworten nur an Absender"; @@ -158,6 +164,8 @@ "Print..." = "Drucken..."; "Delete Message" = "Lõschen"; +"This Folder" = "This Folder"; + /* Label popup menu */ "None" = "Aucune"; "Important" = "Important"; @@ -189,3 +197,11 @@ "Please select a message." = "Sie müssen eine Nachricht auswählen."; "Please select a message to print." = "Sie müssen eine Nachricht zum Drucken auswählen."; "Please select only one message to print." = "Bitte wählen Sie nur eine Nachricht zum Drucken aus."; + +"You need to choose a non-virtual folder!" = "You need to choose a non-virtual folder!"; +"You need to choose a root subfolder!" = "You need to choose a root subfolder!"; + +"Moving a message into its own folder is impossible!" += "Moving a message into its own folder is impossible!"; +"Copying a message into its own folder is impossible!" += "Copying a message into its own folder is impossible!"; diff --git a/UI/MailerUI/UIxMailActions.m b/UI/MailerUI/UIxMailActions.m index 3ebf019c..7b6d9e13 100644 --- a/UI/MailerUI/UIxMailActions.m +++ b/UI/MailerUI/UIxMailActions.m @@ -104,7 +104,7 @@ NSString *destinationFolder; id response; - destinationFolder = [[context request] formValueForKey: @"tofolder"]; + destinationFolder = [[context request] formValueForKey: @"folder"]; if ([destinationFolder length] > 0) { response = [[self clientObject] moveToFolderNamed: destinationFolder @@ -119,6 +119,26 @@ return response; } +- (id) copyAction +{ + NSString *destinationFolder; + id response; + + destinationFolder = [[context request] formValueForKey: @"folder"]; + if ([destinationFolder length] > 0) + { + response = [[self clientObject] copyToFolderNamed: destinationFolder + inContext: context]; + if (!response) + response = [self responseWith204]; + } + else + response = [NSException exceptionWithHTTPStatus: 500 /* Server Error */ + reason: @"No destination folder given"]; + + return response; +} + /* active message */ - (id) markMessageUnreadAction diff --git a/UI/MailerUI/UIxMailFolderActions.m b/UI/MailerUI/UIxMailFolderActions.m index 84d7fa95..ade6ed8d 100644 --- a/UI/MailerUI/UIxMailFolderActions.m +++ b/UI/MailerUI/UIxMailFolderActions.m @@ -24,8 +24,10 @@ #import #import #import +#import #import +#import #import #import #import @@ -35,6 +37,7 @@ #import #import #import +#import #import @@ -172,6 +175,55 @@ return response; } +- (WOResponse *) _setFolderPurpose: (NSString *) purpose +{ + SOGoMailFolder *co; + WOResponse *response; + NSUserDefaults *ud; + NSMutableDictionary *mailSettings; + + co = [self clientObject]; + if ([NSStringFromClass ([co class]) isEqualToString: @"SOGoMailFolder"]) + { + ud = [[context activeUser] userSettings]; + mailSettings = [ud objectForKey: @"Mail"]; + if (!mailSettings) + { + mailSettings = [NSMutableDictionary new]; + [mailSettings autorelease]; + } + [ud setObject: mailSettings forKey: @"Mail"]; + [mailSettings setObject: [co relativeImap4Name] + forKey: [NSString stringWithFormat: @"%@Folder", + purpose]]; + [ud synchronize]; + response = [self responseWith204]; + } + else + { + response = [self responseWithStatus: 500]; + [response + appendContentString: @"Unable to change the purpose of this folder."]; + } + + return response; +} + +- (WOResponse *) setAsDraftsFolderAction +{ + return [self _setFolderPurpose: @"Drafts"]; +} + +- (WOResponse *) setAsSentFolderAction +{ + return [self _setFolderPurpose: @"Sent"]; +} + +- (WOResponse *) setAsTrashFolderAction +{ + return [self _setFolderPurpose: @"Trash"]; +} + - (WOResponse *) expungeAction { NSException *error; diff --git a/UI/MailerUI/product.plist b/UI/MailerUI/product.plist index 73ed0809..083bbe40 100644 --- a/UI/MailerUI/product.plist +++ b/UI/MailerUI/product.plist @@ -140,6 +140,21 @@ actionClass = "UIxMailFolderActions"; actionName = "deleteFolder"; }; + setAsDraftsFolder = { + protectedBy = "View"; + actionClass = "UIxMailFolderActions"; + actionName = "setAsDraftsFolder"; + }; + setAsSentFolder = { + protectedBy = "View"; + actionClass = "UIxMailFolderActions"; + actionName = "setAsSentFolder"; + }; + setAsTrashFolder = { + protectedBy = "View"; + actionClass = "UIxMailFolderActions"; + actionName = "setAsTrashFolder"; + }; userRights = { protectedBy = "ReadAcls"; pageName = "UIxMailUserRightsEditor"; @@ -195,6 +210,11 @@ actionClass = "UIxMailActions"; actionName = "move"; }; + copy = { + protectedBy = "View"; + actionClass = "UIxMailActions"; + actionName = "copy"; + }; trash = { protectedBy = "View"; actionClass = "UIxMailActions"; diff --git a/UI/MainUI/SOGoRootPage.m b/UI/MainUI/SOGoRootPage.m index 9749d13b..8b82c410 100644 --- a/UI/MainUI/SOGoRootPage.m +++ b/UI/MainUI/SOGoRootPage.m @@ -89,7 +89,7 @@ NSString *login, *oldLocation; login = [[context activeUser] login]; - if ([login isEqualToString: @"anonymous"]) + if (!login || [login isEqualToString: @"anonymous"]) response = self; else { diff --git a/UI/SOGoUI/GNUmakefile b/UI/SOGoUI/GNUmakefile index 034e2764..49282322 100644 --- a/UI/SOGoUI/GNUmakefile +++ b/UI/SOGoUI/GNUmakefile @@ -27,8 +27,8 @@ libSOGoUI_OBJC_FILES += \ SOGoAptFormatter.m \ SOGoJSStringFormatter.m \ WOContext+UIx.m \ - \ - SOGoACLAdvisory.m + SOGoACLAdvisory.m \ + SOGoFolderAdvisory.m # make diff --git a/UI/SOGoUI/SOGoACLAdvisory.h b/UI/SOGoUI/SOGoACLAdvisory.h index c6ac9b66..762b89a1 100644 --- a/UI/SOGoUI/SOGoACLAdvisory.h +++ b/UI/SOGoUI/SOGoACLAdvisory.h @@ -47,22 +47,34 @@ @end -@interface SOGoACLEnglishAdditionAdvisory : SOGoACLAdvisory +@interface SOGoACLAdditionAdvisory : SOGoACLAdvisory + +- (NSString *) aclMethod; + +@end + +@interface SOGoACLRemovalAdvisory : SOGoACLAdvisory + +- (NSString *) aclMethod; + +@end + +@interface SOGoACLEnglishAdditionAdvisory : SOGoACLAdditionAdvisory @end -@interface SOGoACLEnglishRemovalAdvisory : SOGoACLAdvisory +@interface SOGoACLFrenchAdditionAdvisory : SOGoACLAdditionAdvisory @end -@interface SOGoACLFrenchAdditionAdvisory : SOGoACLAdvisory +@interface SOGoACLGermanAdditionAdvisory : SOGoACLAdditionAdvisory @end -@interface SOGoACLFrenchRemovalAdvisory : SOGoACLAdvisory +@interface SOGoACLEnglishRemovalAdvisory : SOGoACLRemovalAdvisory @end -@interface SOGoACLGermanAdditionAdvisory : SOGoACLAdvisory +@interface SOGoACLFrenchRemovalAdvisory : SOGoACLRemovalAdvisory @end -@interface SOGoACLGermanRemovalAdvisory : SOGoACLAdvisory +@interface SOGoACLGermanRemovalAdvisory : SOGoACLRemovalAdvisory @end #endif /* SOGOACLADVISORY_H */ diff --git a/UI/SOGoUI/SOGoACLAdvisory.m b/UI/SOGoUI/SOGoACLAdvisory.m index 12c2be31..b52ebcc1 100644 --- a/UI/SOGoUI/SOGoACLAdvisory.m +++ b/UI/SOGoUI/SOGoACLAdvisory.m @@ -31,6 +31,7 @@ #import #import #import +#import #import "SOGoACLAdvisory.h" @@ -109,7 +110,7 @@ subject = [[self generateResponse] contentAsString]; isSubject = NO; - return [subject stringByTrimmingSpaces]; + return [[subject stringByTrimmingSpaces] asQPSubjectString: @"utf-8"]; } - (NSString *) body @@ -126,7 +127,7 @@ - (NSString *) aclMethod { [self subclassResponsibility: _cmd]; - + return nil; } @@ -210,20 +211,32 @@ @end -@implementation SOGoACLEnglishAdditionAdvisory +@implementation SOGoACLAdditionAdvisory + +- (NSString *) aclMethod { return @"add"; } + @end -@implementation SOGoACLEnglishRemovalAdvisory +@implementation SOGoACLRemovalAdvisory + +- (NSString *) aclMethod { return @"remove"; } + @end -@implementation SOGoACLFrenchAdditionAdvisory +@implementation SOGoACLEnglishAdditionAdvisory @end -@implementation SOGoACLFrenchRemovalAdvisory +@implementation SOGoACLFrenchAdditionAdvisory @end @implementation SOGoACLGermanAdditionAdvisory @end +@implementation SOGoACLEnglishRemovalAdvisory +@end + +@implementation SOGoACLFrenchRemovalAdvisory +@end + @implementation SOGoACLGermanRemovalAdvisory @end diff --git a/UI/SOGoUI/SOGoFolderAdvisory.h b/UI/SOGoUI/SOGoFolderAdvisory.h new file mode 100644 index 00000000..3485d4c6 --- /dev/null +++ b/UI/SOGoUI/SOGoFolderAdvisory.h @@ -0,0 +1,68 @@ +/* SOGoFolderAdvisory.h - this file is part of SOGo + * + * Copyright (C) 2007 Inverse groupe conseil + * + * Author: Ludovic Marcotte + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This file 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef SOGOFOLDERADVISORY_H +#define SOGOFOLDERADVISORY_H + +#import "UIxComponent.h" +#import "../../SoObjects/SOGo/SOGoFolder.h" + +@interface SOGoFolderAdvisory : UIxComponent +{ + NSString *recipientUID; + SOGoFolder *folderObject; + BOOL isSubject; + BOOL isBody; +} + +- (void) setFolderObject: (SOGoFolder *) theFolder; +- (void) setRecipientUID: (NSString *) newRecipientUID; +- (void) send; + +- (BOOL) isSubject; +- (BOOL) isBody; + +- (NSString *) subject; +- (NSString *) body; +- (NSString *) folderMethod; + +@end + +@interface SOGoFolderEnglishAdditionAdvisory : SOGoFolderAdvisory +@end + +@interface SOGoFolderEnglishRemovalAdvisory : SOGoFolderAdvisory +@end + +@interface SOGoFolderFrenchAdditionAdvisory : SOGoFolderAdvisory +@end + +@interface SOGoFolderFrenchRemovalAdvisory : SOGoFolderAdvisory +@end + +@interface SOGoFolderGermanAdditionAdvisory : SOGoFolderAdvisory +@end + +@interface SOGoFolderGermanRemovalAdvisory : SOGoFolderAdvisory +@end + +#endif /* SOGOFOLDERADVISORY_H */ diff --git a/UI/SOGoUI/SOGoFolderAdvisory.m b/UI/SOGoUI/SOGoFolderAdvisory.m new file mode 100644 index 00000000..45a1e74e --- /dev/null +++ b/UI/SOGoUI/SOGoFolderAdvisory.m @@ -0,0 +1,232 @@ +/* SOGoFolderAdvisory.m - this file is part of SOGo + * + * Copyright (C) 2007 Inverse groupe conseil + * + * Author: Ludovic Marcotte + * + * This file is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This file 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#import + +#import +#import +#import +#import +#import + +#import +#import +#import +#import +#import +#import + +#import "SOGoFolderAdvisory.h" + +@implementation SOGoFolderAdvisory + +- (id) init +{ + if ((self = [super init])) + { + recipientUID = nil; + folderObject = nil; + isSubject = NO; + isBody = NO; + } + + return self; +} + +- (void) dealloc +{ + [recipientUID release]; + [folderObject release]; + [super dealloc]; +} + +- (void) setFolderObject: (SOGoFolder *) theFolder +{ + ASSIGN(folderObject, theFolder); +} + +- (void) setRecipientUID: (NSString *) newRecipientUID +{ + ASSIGN (recipientUID, newRecipientUID); +} + +- (BOOL) isSubject +{ + return isSubject; +} + +- (BOOL) isBody +{ + return isBody; +} + +- (NSString *) displayName +{ + return [folderObject displayName]; +} + +- (NSString *) httpFolderURL +{ + NSString *absoluteString; + NSMutableString *url; + +#warning the url returned by SOGoMail may be empty, we need to handle that + absoluteString = [[folderObject soURL] absoluteString]; + url = [NSMutableString stringWithString: absoluteString]; + + if (![url hasSuffix: @"/"]) + [url appendString: @"/"]; + + return url; +} + +- (NSString *) subject +{ + NSString *subject; + + isSubject = YES; + subject = [[self generateResponse] contentAsString]; + isSubject = NO; + + return [[subject stringByTrimmingSpaces] asQPSubjectString: @"utf-8"]; +} + +- (NSString *) body +{ + NSString *body; + + isBody = YES; + body = [[self generateResponse] contentAsString]; + isBody = NO; + + return [body stringByTrimmingSpaces]; +} + +- (NSString *) folderMethod +{ + [self subclassResponsibility: _cmd]; + + return nil; +} + +- (NGMimeBodyPart *) _textPart +{ + NGMutableHashMap *headerMap; + NGMimeBodyPart *part; + NSData *body; + + headerMap = [NGMutableHashMap hashMapWithCapacity: 1]; + [headerMap setObject: @"text/plain; charset=utf-8" forKey: @"content-type"]; + + part = [NGMimeBodyPart bodyPartWithHeader: headerMap]; + body = [[self body] dataUsingEncoding: NSUTF8StringEncoding]; + [part setBody: [self body]]; + + return part; +} + +- (NGMimeBodyPart *) _sogoNotificationPart +{ + NGMutableHashMap *headerMap; + NGMimeBodyPart *part; + NSData *body; + + /* calendar part */ + headerMap = [NGMutableHashMap hashMapWithCapacity: 1]; + [headerMap setObject: [NSString stringWithFormat: + @"%@; method=%@; type=%@; charset=%@", + @"application/x-sogo-notification", + [self folderMethod], [folderObject folderType], + @"utf-8"] + forKey: @"content-type"]; + + part = [NGMimeBodyPart bodyPartWithHeader: headerMap]; + body = [[self httpFolderURL] dataUsingEncoding: NSUTF8StringEncoding]; + [part setBody: body]; + + return part; +} + +- (void) send +{ + NSString *recipient, *date; + NGMutableHashMap *headerMap; + NGMimeMessage *message; + NGMimeMultipartBody *body; + SOGoUser *activeUser; + NSDictionary *identity; + NSString *from, *fullMail; + + activeUser = [context activeUser]; + identity = [activeUser primaryIdentity]; + from = [identity objectForKey: @"email"]; + fullMail = [NSString stringWithFormat: @"%@ <%@>", + [identity objectForKey: @"fullName"], from]; + + recipient = [[LDAPUserManager sharedUserManager] + getFullEmailForUID: recipientUID]; + + headerMap = [NGMutableHashMap hashMapWithCapacity: 5]; + [headerMap setObject: @"multipart/alternative" forKey: @"content-type"]; + [headerMap setObject: fullMail forKey: @"From"]; + [headerMap setObject: recipient forKey: @"To"]; + date = [[NSCalendarDate date] rfc822DateString]; + [headerMap setObject: date forKey: @"Date"]; + [headerMap setObject: [self subject] forKey: @"Subject"]; + message = [NGMimeMessage messageWithHeader: headerMap]; + + body = [[NGMimeMultipartBody alloc] initWithPart: message]; + [body addBodyPart: [self _textPart]]; + [body addBodyPart: [self _sogoNotificationPart]]; + [message setBody: body]; + [body release]; + + [[SOGoMailer sharedMailer] sendMimePart: message + toRecipients: [NSArray arrayWithObject: recipient] + sender: from]; +} + +@end + +@implementation SOGoFolderEnglishAdditionAdvisory +- (NSString *) folderMethod { return @"add"; } +@end + +@implementation SOGoFolderEnglishRemovalAdvisory +- (NSString *) folderMethod { return @"remove"; } +@end + +@implementation SOGoFolderFrenchAdditionAdvisory +- (NSString *) folderMethod { return @"add"; } +@end + +@implementation SOGoFolderFrenchRemovalAdvisory +- (NSString *) folderMethod { return @"remove"; } +@end + +@implementation SOGoFolderGermanAdditionAdvisory +- (NSString *) folderMethod { return @"add"; } +@end + +@implementation SOGoFolderGermanRemovalAdvisory +- (NSString *) folderMethod { return @"remove"; } +@end diff --git a/UI/Scheduler/UIxAppointmentEditor.m b/UI/Scheduler/UIxAppointmentEditor.m index 4f4fb0bb..de4e0c47 100644 --- a/UI/Scheduler/UIxAppointmentEditor.m +++ b/UI/Scheduler/UIxAppointmentEditor.m @@ -20,8 +20,6 @@ * Boston, MA 02111-1307, USA. */ -#warning WE LEAK IVARS LIKE CRAZY HERE - #include #import @@ -60,7 +58,10 @@ - (void) dealloc { - RELEASE(repeat); + [item release]; + [repeat release]; + [aptStartDate release]; + [aptEndDate release]; [super dealloc]; } @@ -142,14 +143,12 @@ else text = [self labelForKey: [NSString stringWithFormat: @"repeat_%@", item]]; - NSLog(@"itemRepeatText: %@", text); - return text; } - (void) setItem: (NSString *) newItem { - item = newItem; + ASSIGN (item, newItem); } - (NSString *) item @@ -196,6 +195,15 @@ // return reminder; // } +- (NSString *) reminder +{ + return @""; +} + +- (void) setReminder: (NSString *) newReminder +{ +} + - (NSString *) itemReminderText { NSString *text; @@ -215,16 +223,7 @@ - (void) setRepeat: (NSString *) newRepeat { - ASSIGN(repeat, newRepeat); -} - -- (NSString *) reminder -{ - return @""; -} - -- (void) setReminder: (NSString *) newReminder -{ + ASSIGN (repeat, newRepeat); } /* actions */ @@ -262,6 +261,7 @@ NSCalendarDate *startDate, *endDate; NSString *duration; unsigned int minutes; + iCalRecurrenceRule *rule; event = (iCalEvent *) [[self clientObject] component: NO]; if (event) @@ -292,29 +292,37 @@ // We initialize our repeat ivars if ([event hasRecurrenceRules]) { - iCalRecurrenceRule *rule; - repeat = @"CUSTOM"; rule = [[event recurrenceRules] lastObject]; if ([rule frequency] == iCalRecurrenceFrequenceWeekly) { - if ([rule repeatInterval] == 1) repeat = @"WEEKLY"; - else if ([rule repeatInterval] == 2) repeat = @"BI-WEEKLY"; + if ([rule repeatInterval] == 1) + repeat = @"WEEKLY"; + else if ([rule repeatInterval] == 2) + repeat = @"BI-WEEKLY"; } else if ([rule frequency] == iCalRecurrenceFrequenceDaily) { - if ([rule byDayMask] == (iCalWeekDayMonday|iCalWeekDayTuesday|iCalWeekDayWednesday|iCalWeekDayThursday|iCalWeekDayFriday)) repeat = @"EVERY WEEKDAY"; - else if (![rule byDayMask]) repeat = @"DAILY"; + if ([rule byDayMask] == (iCalWeekDayMonday + | iCalWeekDayTuesday + | iCalWeekDayWednesday + | iCalWeekDayThursday + | iCalWeekDayFriday)) + repeat = @"EVERY WEEKDAY"; + else if (![rule byDayMask]) + repeat = @"DAILY"; } - else if ([rule frequency] == iCalRecurrenceFrequenceMonthly && [rule repeatInterval] == 1) repeat = @"MONTHLY"; - else if ([rule frequency] == iCalRecurrenceFrequenceYearly && [rule repeatInterval] == 1) repeat = @"YEARLY"; + else if ([rule frequency] == iCalRecurrenceFrequenceMonthly + && [rule repeatInterval] == 1) + repeat = @"MONTHLY"; + else if ([rule frequency] == iCalRecurrenceFrequenceYearly + && [rule repeatInterval] == 1) + repeat = @"YEARLY"; } else - { - DESTROY(repeat); - } + DESTROY(repeat); return self; } @@ -373,6 +381,7 @@ { SOGoAppointmentObject *clientObject; int nbrDays; + iCalRecurrenceRule *rule; clientObject = [self clientObject]; event = (iCalEvent *) [clientObject component: YES]; @@ -396,15 +405,13 @@ // We remove any repeat rules if (!repeat && [event hasRecurrenceRules]) + [event removeAllRecurrenceRules]; + else if (!([repeat caseInsensitiveCompare: @"-"] == NSOrderedSame + || [repeat caseInsensitiveCompare: @"CUSTOM"] == NSOrderedSame)) { - [event removeAllRecurrenceRules]; - } - else if (!([repeat caseInsensitiveCompare: @"-"] == NSOrderedSame || [repeat caseInsensitiveCompare: @"CUSTOM"] == NSOrderedSame)) - { - iCalRecurrenceRule *rule; - - rule = [[iCalRecurrenceRule alloc] init]; + rule = [iCalRecurrenceRule new]; + [rule setInterval: @"1"]; if ([repeat caseInsensitiveCompare: @"BI-WEEKLY"] == NSOrderedSame) { [rule setFrequency: iCalRecurrenceFrequenceWeekly]; @@ -412,17 +419,18 @@ } else if ([repeat caseInsensitiveCompare: @"EVERY WEEKDAY"] == NSOrderedSame) { - [rule setByDayMask: (iCalWeekDayMonday|iCalWeekDayTuesday|iCalWeekDayWednesday|iCalWeekDayThursday|iCalWeekDayFriday)]; + [rule setByDayMask: (iCalWeekDayMonday + |iCalWeekDayTuesday + |iCalWeekDayWednesday + |iCalWeekDayThursday + |iCalWeekDayFriday)]; [rule setFrequency: iCalRecurrenceFrequenceDaily]; - [rule setInterval: @"1"]; } else - { - [rule setFrequency: (iCalRecurrenceFrequency)[rule valueForFrequency: repeat]]; - [rule setInterval: @"1"]; - } + [rule setFrequency: + (iCalRecurrenceFrequency) [rule valueForFrequency: repeat]]; [event setRecurrenceRules: [NSArray arrayWithObject: rule]]; - RELEASE(rule); + [rule release]; } } diff --git a/UI/Templates/ContactsUI/UIxContactEditor.wox b/UI/Templates/ContactsUI/UIxContactEditor.wox index c1c1b45e..af3e3b02 100644 --- a/UI/Templates/ContactsUI/UIxContactEditor.wox +++ b/UI/Templates/ContactsUI/UIxContactEditor.wox @@ -348,8 +348,4 @@ onclick="window.close(); return false;" /> - - diff --git a/UI/Templates/ContactsUI/UIxContactsUserFolders.wox b/UI/Templates/ContactsUI/UIxContactsUserFolders.wox index b6b95e63..9b5e19f2 100644 --- a/UI/Templates/ContactsUI/UIxContactsUserFolders.wox +++ b/UI/Templates/ContactsUI/UIxContactsUserFolders.wox @@ -10,11 +10,10 @@ className="UIxPageFrame" title="name" const:toolbar="none" - const:popup="YES"> - + const:popup="YES" + const:jsFiles="dtree.js"> -
-
+
diff --git a/UI/Templates/MailerUI/UIxMailEditor.wox b/UI/Templates/MailerUI/UIxMailEditor.wox index bfc1976a..bbc56eb0 100644 --- a/UI/Templates/MailerUI/UIxMailEditor.wox +++ b/UI/Templates/MailerUI/UIxMailEditor.wox @@ -9,7 +9,8 @@ xmlns:label="OGo:label" className="UIxPageFrame" title="panelTitle" - const:popup="YES"> + const:popup="YES" + const:jsFiles="UIxMailToSelection.js">