diff --git a/SoObjects/Mailer/GNUmakefile b/SoObjects/Mailer/GNUmakefile index 7b713f54d..411bbc2bb 100644 --- a/SoObjects/Mailer/GNUmakefile +++ b/SoObjects/Mailer/GNUmakefile @@ -24,6 +24,7 @@ Mailer_OBJC_FILES += \ SOGoDraftsFolder.m \ SOGoTrashFolder.m \ SOGoJunkFolder.m \ + SOGoTemplatesFolder.m \ \ SOGoMailBodyPart.m \ SOGoHTMLMailBodyPart.m \ diff --git a/SoObjects/Mailer/SOGoMailAccount.h b/SoObjects/Mailer/SOGoMailAccount.h index 58f80cf45..dc90471ca 100644 --- a/SoObjects/Mailer/SOGoMailAccount.h +++ b/SoObjects/Mailer/SOGoMailAccount.h @@ -44,6 +44,7 @@ @class SOGoSentFolder; @class SOGoTrashFolder; @class SOGoJunkFolder; +@class SOGoTemplatesFolder; typedef enum { undefined = -1, @@ -63,6 +64,7 @@ typedef enum { SOGoSentFolder *sentFolder; SOGoTrashFolder *trashFolder; SOGoJunkFolder *junkFolder; + SOGoTemplatesFolder *templatesFolder; SOGoIMAPAclStyle imapAclStyle; NSMutableArray *identities; NSString *otherUsersFolderName; @@ -117,12 +119,14 @@ typedef enum { - (NSString *) otherUsersFolderNameInContext: (id)_ctx; - (NSString *) sharedFoldersNameInContext: (id)_ctx; - (NSString *) junkFolderNameInContext: (id)_ctx; +- (NSString *) templatesFolderNameInContext: (id)_ctx; - (SOGoMailFolder *) inboxFolderInContext: (id)_ctx; - (SOGoDraftsFolder *) draftsFolderInContext: (id)_ctx; - (SOGoSentFolder *) sentFolderInContext: (id)_ctx; - (SOGoTrashFolder *) trashFolderInContext: (id)_ctx; - (SOGoJunkFolder *) junkFolderInContext: (id)_ctx; +- (SOGoTemplatesFolder *) templatesFolderInContext: (id)_ctx; /* namespaces */ diff --git a/SoObjects/Mailer/SOGoMailAccount.m b/SoObjects/Mailer/SOGoMailAccount.m index a474e1a64..7c16c3831 100644 --- a/SoObjects/Mailer/SOGoMailAccount.m +++ b/SoObjects/Mailer/SOGoMailAccount.m @@ -48,6 +48,7 @@ #import "SOGoSentFolder.h" #import "SOGoTrashFolder.h" #import "SOGoJunkFolder.h" +#import "SOGoTemplatesFolder.h" #import "SOGoUser+Mailer.h" #import "SOGoMailAccount.h" @@ -70,6 +71,7 @@ static NSString *inboxFolderName = @"INBOX"; sentFolder = nil; trashFolder = nil; junkFolder = nil; + templatesFolder = nil; imapAclStyle = undefined; identities = nil; otherUsersFolderName = nil; @@ -88,6 +90,7 @@ static NSString *inboxFolderName = @"INBOX"; [sentFolder release]; [trashFolder release]; [junkFolder release]; + [templatesFolder release]; [identities release]; [otherUsersFolderName release]; [sharedFoldersName release]; @@ -100,6 +103,11 @@ static NSString *inboxFolderName = @"INBOX"; return NO; } +- (BOOL) isInTemplatesFolder +{ + return NO; +} + - (void) _appendNamespace: (NSArray *) namespace toFolders: (NSMutableArray *) folders { @@ -406,6 +414,7 @@ static NSString *inboxFolderName = @"INBOX"; [self sentFolderNameInContext: context], [self trashFolderNameInContext: context], [self junkFolderNameInContext: context], + [self templatesFolderNameInContext: context], nil] stringsWithFormat: @"/%@"]; folders = [[self imap4Connection] allFoldersForURL: [self imap4URL] onlySubscribedFolders: subscribedOnly]; @@ -479,6 +488,9 @@ static NSString *inboxFolderName = @"INBOX"; else if ([flags containsObject: [self junkFolderNameInContext: context]] || [folderName isEqualToString: [self junkFolderNameInContext: context]]) folderType = @"junk"; + else if ([flags containsObject: [self templatesFolderNameInContext: context]] || + [folderName isEqualToString: [self templatesFolderNameInContext: context]]) + folderType = @"templates"; else if ([folderName isEqualToString: otherUsersFolderName]) folderType = @"otherUsers"; else if ([folderName isEqualToString: sharedFoldersName]) @@ -1012,6 +1024,9 @@ static NSString *inboxFolderName = @"INBOX"; else if ([folderName isEqualToString: [self junkFolderNameInContext: _ctx]]) klazz = [SOGoJunkFolder class]; + else if ([folderName + isEqualToString: [self templatesFolderNameInContext: _ctx]]) + klazz = [SOGoTemplatesFolder class]; else klazz = [SOGoMailFolder class]; @@ -1081,6 +1096,11 @@ static NSString *inboxFolderName = @"INBOX"; return [self _userFolderNameWithPurpose: @"Junk"]; } +- (NSString *) templatesFolderNameInContext: (id)_ctx +{ + return [self _userFolderNameWithPurpose: @"Templates"]; +} + - (NSString *) otherUsersFolderNameInContext: (id)_ctx { return otherUsersFolderName; @@ -1192,6 +1212,19 @@ static NSString *inboxFolderName = @"INBOX"; return junkFolder; } +- (SOGoTemplatesFolder *) templatesFolderInContext: (id) _ctx +{ + if (!templatesFolder) + { + templatesFolder + = [self folderWithTraversal: [self templatesFolderNameInContext: _ctx] + andClassName: @"SOGoTemplatesFolder"]; + [templatesFolder retain]; + } + + return templatesFolder; +} + /* account delegation */ - (NSArray *) delegates { diff --git a/SoObjects/Mailer/SOGoMailBaseObject.h b/SoObjects/Mailer/SOGoMailBaseObject.h index 97d06690d..43306d76a 100644 --- a/SoObjects/Mailer/SOGoMailBaseObject.h +++ b/SoObjects/Mailer/SOGoMailBaseObject.h @@ -62,6 +62,7 @@ - (SOGoMailAccount *) mailAccountFolder; - (SOGoMailAccounts *) mailAccountsFolder; - (BOOL) isInDraftsFolder; +- (BOOL) isInTemplatesFolder; /* IMAP4 */ diff --git a/SoObjects/Mailer/SOGoMailBaseObject.m b/SoObjects/Mailer/SOGoMailBaseObject.m index 9d415c67a..b59b94a86 100644 --- a/SoObjects/Mailer/SOGoMailBaseObject.m +++ b/SoObjects/Mailer/SOGoMailBaseObject.m @@ -121,6 +121,11 @@ return [container isInDraftsFolder]; } +- (BOOL) isInTemplatesFolder +{ + return [container isInTemplatesFolder]; +} + /* IMAP4 */ - (NGImap4ConnectionManager *) mailManager diff --git a/SoObjects/Mailer/SOGoMailFolder.m b/SoObjects/Mailer/SOGoMailFolder.m index 997407c36..3cc47114d 100644 --- a/SoObjects/Mailer/SOGoMailFolder.m +++ b/SoObjects/Mailer/SOGoMailFolder.m @@ -1144,6 +1144,10 @@ static NSInteger _compareFetchResultsByUID (id entry1, id entry2, NSArray *uids) isEqualToString: [mailAccount junkFolderNameInContext: _ctx]]) className = @"SOGoJunkFolder"; + else if ([fullFolderName + isEqualToString: + [mailAccount templatesFolderNameInContext: _ctx]]) + className = @"SOGoTemplatesFolder"; /* else if ([folderName isEqualToString: [mailAccount sieveFolderNameInContext: _ctx]]) obj = [self lookupFiltersFolder: _key inContext: _ctx]; */ diff --git a/SoObjects/Mailer/SOGoTemplatesFolder.h b/SoObjects/Mailer/SOGoTemplatesFolder.h new file mode 100644 index 000000000..9bcb61187 --- /dev/null +++ b/SoObjects/Mailer/SOGoTemplatesFolder.h @@ -0,0 +1,32 @@ +/* + Copyright (C) 2022 Inverse inc. + + This file is part of SOGo. + + SOGo is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + SOGo 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 Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with OGo; see the file COPYING. If not, write to the + Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. +*/ + +#ifndef __Mailer_SOGoTemplatesFolder_H__ +#define __Mailer_SOGoTemplatesFolder_H__ + +#import "SOGoDraftsFolder.h" + +@class SOGoDraftsFolder; + +@interface SOGoTemplatesFolder : SOGoDraftsFolder +@end + +#endif /* __Mailer_SOGoTemplatesFolder_H__ */ diff --git a/SoObjects/Mailer/SOGoTemplatesFolder.m b/SoObjects/Mailer/SOGoTemplatesFolder.m new file mode 100644 index 000000000..b732a7d35 --- /dev/null +++ b/SoObjects/Mailer/SOGoTemplatesFolder.m @@ -0,0 +1,31 @@ +/* + Copyright (C) 2022 Inverse inc. + + This file is part of SOGo. + + SOGo is free software; you can redistribute it and/or modify it under + the terms of the GNU Lesser General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + + SOGo 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 Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with OGo; see the file COPYING. If not, write to the + Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. +*/ + +#import "SOGoTemplatesFolder.h" + +@implementation SOGoTemplatesFolder + +- (BOOL) isInTemplatesFolder +{ + return YES; +} + +@end /* SOGoTemplatesFolder */ diff --git a/SoObjects/SOGo/SOGoDefaults.plist b/SoObjects/SOGo/SOGoDefaults.plist index a158ad5c7..9ba853590 100644 --- a/SoObjects/SOGo/SOGoDefaults.plist +++ b/SoObjects/SOGo/SOGoDefaults.plist @@ -115,6 +115,7 @@ SOGoDraftsFolderName = "Drafts"; SOGoTrashFolderName = "Trash"; SOGoJunkFolderName = "Junk"; + SOGoTemplatesFolderName = "Templates"; SOGoMailComposeMessageType = "html"; SOGoMailComposeFontSize = "0"; SOGoMailDisplayRemoteInlineImages = "never"; diff --git a/SoObjects/SOGo/SOGoUser.m b/SoObjects/SOGo/SOGoUser.m index 7edbce1f7..1255ec231 100644 --- a/SoObjects/SOGo/SOGoUser.m +++ b/SoObjects/SOGo/SOGoUser.m @@ -923,6 +923,8 @@ forKey: @"Trash"]; [mailboxes setObject: [_defaults junkFolderName] forKey: @"Junk"]; + [mailboxes setObject: [_defaults templatesFolderName] + forKey: @"Templates"]; [mailAccount setObject: mailboxes forKey: @"specialMailboxes"]; [mailboxes release]; diff --git a/SoObjects/SOGo/SOGoUserDefaults.h b/SoObjects/SOGo/SOGoUserDefaults.h index 12f3ee33a..106b2660a 100644 --- a/SoObjects/SOGo/SOGoUserDefaults.h +++ b/SoObjects/SOGo/SOGoUserDefaults.h @@ -111,6 +111,9 @@ extern NSString *SOGoWeekStartFirstFullWeek; - (void) setJunkFolderName: (NSString *) newValue; - (NSString *) junkFolderName; +- (void) setTemplatesFolderName: (NSString *) newValue; +- (NSString *) templatesFolderName; + - (void) setFirstDayOfWeek: (int) newValue; - (int) firstDayOfWeek; diff --git a/SoObjects/SOGo/SOGoUserDefaults.m b/SoObjects/SOGo/SOGoUserDefaults.m index 5e2f021db..ae9fab4ba 100644 --- a/SoObjects/SOGo/SOGoUserDefaults.m +++ b/SoObjects/SOGo/SOGoUserDefaults.m @@ -492,6 +492,17 @@ NSString *SOGoWeekStartFirstFullWeek = @"FirstFullWeek"; stringByEncodingImap4FolderName]; } +- (void) setTemplatesFolderName: (NSString *) newValue +{ + [self setObject: newValue forKey: @"SOGoTemplatesFolderName"]; +} + +- (NSString *) templatesFolderName +{ + return [[self stringForKey: @"SOGoTemplatesFolderName"] + stringByEncodingImap4FolderName]; +} + - (void) setFirstDayOfWeek: (int) newValue { [self setInteger: newValue forKey: @"SOGoFirstDayOfWeek"]; diff --git a/UI/MailerUI/English.lproj/Localizable.strings b/UI/MailerUI/English.lproj/Localizable.strings index 7ebedc694..9edf491f9 100644 --- a/UI/MailerUI/English.lproj/Localizable.strings +++ b/UI/MailerUI/English.lproj/Localizable.strings @@ -187,6 +187,7 @@ "InboxFolderName" = "Inbox"; "DraftsFolderName" = "Drafts"; "JunkFolderName" = "Junk"; +"TemplatesFolderName" = "Templates"; "SieveFolderName" = "Filters"; "Folders" = "Folders"; /* title line */ @@ -432,6 +433,9 @@ "Set as Sent" = "Set as Sent"; "Set as Trash" = "Set as Trash"; +/* Set the folder as the one holding the Templates */ +"Set as Templates" = "Set as Templates"; + /* Set the folder as the one holding Junk mails */ "Set as Junk" = "Set as Junk"; @@ -454,6 +458,9 @@ "Your email has been sent" = "Your email has been sent"; "Folder compacted" = "Folder compacted"; +"New draft" = "New draft"; +"Create new draft with this template" = "Create new draft with this template"; + /* Advanced search */ "Enter Subject" = "Enter Subject"; "Enter From" = "Enter From"; diff --git a/UI/MailerUI/UIxMailActions.m b/UI/MailerUI/UIxMailActions.m index 69a27d9cf..5333ffd0f 100644 --- a/UI/MailerUI/UIxMailActions.m +++ b/UI/MailerUI/UIxMailActions.m @@ -118,6 +118,36 @@ andString: [data jsonRepresentation]]; } +- (WOResponse *) composeAction +{ + SOGoMailAccount *account; + SOGoMailObject *co; + SOGoDraftsFolder *drafts; + SOGoDraftObject *newMail; + NSString *accountName, *mailboxName, *messageName; + NSDictionary *data; + + co = [self clientObject]; + account = [co mailAccountFolder]; + drafts = [account draftsFolderInContext: context]; + newMail = [drafts newDraft]; + [newMail fetchMailForEditing: co]; + [newMail storeInfo]; + + accountName = [account nameInContainer]; + mailboxName = [drafts absoluteImap4Name]; + mailboxName = [mailboxName substringWithRange: NSMakeRange(1, [mailboxName length] -2)]; + messageName = [newMail nameInContainer]; + + data = [NSDictionary dictionaryWithObjectsAndKeys: + accountName, @"accountId", + mailboxName, @"mailboxPath", + messageName, @"draftId", nil]; + + return [self responseWithStatus: 201 + andString: [data jsonRepresentation]]; +} + - (WOResponse *) viewPlainAction { BOOL htmlContent; diff --git a/UI/MailerUI/UIxMailView.m b/UI/MailerUI/UIxMailView.m index e7be2fe13..fe373a2d8 100644 --- a/UI/MailerUI/UIxMailView.m +++ b/UI/MailerUI/UIxMailView.m @@ -68,6 +68,7 @@ } - (BOOL) mailIsDraft; +- (BOOL) mailIsTemplate; - (NSNumber *) shouldAskReceipt; - (NSString *) formattedDate; - (NSString *) _matchingIdentityEMailOrDefault: (BOOL) useDefault; @@ -340,6 +341,7 @@ static NSString *mailETag = nil; data = [NSMutableDictionary dictionaryWithObjectsAndKeys: [self shouldAskReceipt], @"shouldAskReceipt", [NSNumber numberWithBool: [self mailIsDraft]], @"isDraft", + [NSNumber numberWithBool: [self mailIsTemplate]], @"isTemplate", renderedPart, @"parts", nil]; if ([self formattedDate]) @@ -803,6 +805,11 @@ static NSString *mailETag = nil; return [[self clientObject] isInDraftsFolder]; } +- (BOOL) mailIsTemplate +{ + return [[self clientObject] isInTemplatesFolder]; +} + - (id) redirectToParentFolder { id url; diff --git a/UI/MailerUI/product.plist b/UI/MailerUI/product.plist index d7700d7c8..5f55a4f59 100644 --- a/UI/MailerUI/product.plist +++ b/UI/MailerUI/product.plist @@ -119,6 +119,11 @@ actionClass = "UIxMailFolderActions"; actionName = "setAsJunkFolder"; }; + setAsTemplatesFolder = { + protectedBy = "View"; + actionClass = "UIxMailFolderActions"; + actionName = "setAsTemplatesFolder"; + }; markMessagesAsJunk = { protectedBy = "View"; actionClass = "UIxMailFolderActions"; @@ -237,6 +242,11 @@ actionClass = "UIxMailActions"; actionName = "edit"; }; + compose = { + protectedBy = "View"; + actionClass = "UIxMailActions"; + actionName = "compose"; + }; reply = { protectedBy = "View"; actionClass = "UIxMailActions"; diff --git a/UI/Templates/MailerUI/UIxMailEditor.wox b/UI/Templates/MailerUI/UIxMailEditor.wox index ce4a0a99c..67d0b00f4 100644 --- a/UI/Templates/MailerUI/UIxMailEditor.wox +++ b/UI/Templates/MailerUI/UIxMailEditor.wox @@ -60,7 +60,9 @@