From d2b023fe2c613f44b61a784028697e5a1643cb62 Mon Sep 17 00:00:00 2001 From: wolfgang Date: Mon, 22 Oct 2007 22:02:17 +0000 Subject: [PATCH] git-svn-id: http://svn.opengroupware.org/SOGo/inverse/trunk@1192 d1b88da0-ebda-0310-925b-ed51d893ca5b --- ChangeLog | 31 ++ Main/sogod.m | 3 +- NEWS | 4 +- SOPE/sope-patchset-r1545.diff | 510 ++++++++++++++++++ SoObjects/Mailer/SOGoMailAccount.m | 1 + SoObjects/Mailer/SOGoMailFolder.h | 18 +- SoObjects/Mailer/SOGoMailFolder.m | 42 +- SoObjects/SOGo/SOGoContentObject.m | 2 + SoObjects/SOGo/SOGoFolder.m | 23 +- UI/MailerUI/English.lproj/Localizable.strings | 5 + UI/MailerUI/French.lproj/Localizable.strings | 5 + UI/MailerUI/German.lproj/Localizable.strings | 5 + UI/MailerUI/UIxMailActions.m | 108 ++++ UI/MailerUI/UIxMailFolderActions.m | 2 +- UI/MailerUI/UIxMailListView.m | 17 + UI/MailerUI/product.plist | 55 ++ UI/MainUI/product.plist | 2 + .../ContactsUI/UIxContactsFilterPanel.wox | 2 +- UI/Templates/MailerUI/UIxMailFilterPanel.wox | 2 +- UI/Templates/MailerUI/UIxMailListView.wox | 3 +- UI/Templates/MailerUI/UIxMailMainFrame.wox | 12 +- .../SchedulerUI/UIxCalFilterPanel.wox | 2 +- .../SchedulerUI/UIxComponentEditor.wox | 2 +- UI/WebServerResources/MailerUI.css | 58 +- UI/WebServerResources/MailerUI.js | 113 +++- .../UIxAppointmentEditor.css | 10 - UI/WebServerResources/UIxMailEditor.js | 9 +- UI/WebServerResources/UIxTaskEditor.css | 10 - UI/WebServerResources/generic.css | 28 +- UI/WebServerResources/generic.js | 11 +- 30 files changed, 1007 insertions(+), 88 deletions(-) create mode 100644 SOPE/sope-patchset-r1545.diff diff --git a/ChangeLog b/ChangeLog index 33493d6d..63b2fea8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,34 @@ +2007-10-22 Wolfgang Sourdeau + + * UI/MailerUI/UIxMailActions.m ([UIxMailActions + -removeAllLabelsAction]): new method that removes all label flags + from the associated message. + ([UIxMailActions -addLabel1Action] + [UIxMailActions -addLabel2Action] + [UIxMailActions -addLabel3Action + [UIxMailActions -addLabel4Action] + [UIxMailActions -addLabel5Action]): new methods that adds label + flags to the associated message. + ([UIxMailActions -removeLabel1Action] + [UIxMailActions -removeLabel2Action] + [UIxMailActions -removeLabel3Action + [UIxMailActions -removeLabel4Action] + [UIxMailActions -removeLabel5Action]): new methods that removes + label flags from the associated message. + + * UI/MailerUI/UIxMailListView.m ([UIxMailListView -msgLabels]): + new accessor that returns the labels associated with the message. + + * SoObjects/Mailer/SOGoMailFolder.m ([SOGoMailFolder + -allFolderPaths]): new method that returns all the paths of all + the subfolders of the folder object. + ([SOGoMailFolder -allFolderURLs]): new method replacing + subfoldersURL. + + * SoObjects/SOGo/SOGoContentObject.m ([SOGoContentObject + -aclsForUser:uid]): object inherits the 'SOGoRole_ObjectEditor' + role from its parent folder. + 2007-10-19 Francis Lachapelle * SoObjects/SOGo/SOGoUser.m diff --git a/Main/sogod.m b/Main/sogod.m index fc858303..8c13c038 100644 --- a/Main/sogod.m +++ b/Main/sogod.m @@ -43,7 +43,8 @@ main (int argc, char **argv, char **env) if (getuid() > 0) { #if LIB_FOUNDATION_LIBRARY - [NSProcessInfo initializeWithArguments: argv count: argc environment: env]; + [NSProcessInfo initializeWithArguments: argv + count: argc environment: env]; #endif ud = [NSUserDefaults standardUserDefaults]; rc = 0; diff --git a/NEWS b/NEWS index 95e1bff6..e563d7fb 100644 --- a/NEWS +++ b/NEWS @@ -2,9 +2,7 @@ -------------- - 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 --------------- +- added the ability to label messages; - implemented cookie-based identification in the web interface; - fixed a bug where a false positive happening whenever a wrong user login was given during an indirect bind; diff --git a/SOPE/sope-patchset-r1545.diff b/SOPE/sope-patchset-r1545.diff new file mode 100644 index 00000000..5a61450b --- /dev/null +++ b/SOPE/sope-patchset-r1545.diff @@ -0,0 +1,510 @@ +Index: sope-gdl1/PostgreSQL/PostgreSQL72Channel.h +=================================================================== +--- sope-gdl1/PostgreSQL/PostgreSQL72Channel.h (révision 1545) ++++ sope-gdl1/PostgreSQL/PostgreSQL72Channel.h (copie de travail) +@@ -28,6 +28,7 @@ + #define ___PostgreSQL72_Channel_H___ + + #include ++#include + #include + + @class NSArray, NSString, NSMutableDictionary; +@@ -40,7 +41,7 @@ + int modification; + } PostgreSQL72FieldInfo; + +-@interface PostgreSQL72Channel : EOAdaptorChannel ++@interface PostgreSQL72Channel : EOAdaptorChannel + { + // connection is valid after an openChannel call + PGConnection *connection; +Index: sope-gdl1/PostgreSQL/PostgreSQL72Channel.m +=================================================================== +--- sope-gdl1/PostgreSQL/PostgreSQL72Channel.m (révision 1545) ++++ sope-gdl1/PostgreSQL/PostgreSQL72Channel.m (copie de travail) +@@ -713,6 +713,39 @@ + return ms; + } + ++/* GCSEOAdaptorChannel protocol */ ++static NSString *sqlFolderFormat = (@"CREATE TABLE %@ (\n" \ ++ @" c_name VARCHAR (256) NOT NULL,\n" ++ @" c_content VARCHAR (100000) NOT NULL,\n" ++ @" c_creationdate INT4 NOT NULL,\n" ++ @" c_lastmodified INT4 NOT NULL,\n" ++ @" c_version INT4 NOT NULL,\n" ++ @" c_deleted INT4 NULL\n" ++ @")"); ++static NSString *sqlFolderACLFormat = (@"CREATE TABLE %@ (\n" \ ++ @" c_uid VARCHAR (256) NOT NULL,\n" ++ @" c_object VARCHAR (256) NOT NULL,\n" ++ @" c_role VARCHAR (80) NOT NULL\n" ++ @")"); ++ ++- (NSException *) createGCSFolderTableWithName: (NSString *) tableName ++{ ++ NSString *sql; ++ ++ sql = [NSString stringWithFormat: sqlFolderFormat, tableName]; ++ ++ return [self evaluateExpressionX: sql]; ++} ++ ++- (NSException *) createGCSFolderACLTableWithName: (NSString *) tableName ++{ ++ NSString *sql; ++ ++ sql = [NSString stringWithFormat: sqlFolderACLFormat, tableName]; ++ ++ return [self evaluateExpressionX: sql]; ++} ++ + @end /* PostgreSQL72Channel */ + + @implementation PostgreSQL72Channel(PrimaryKeyGeneration) +Index: sope-gdl1/Oracle8/ChangeLog +=================================================================== +--- sope-gdl1/Oracle8/ChangeLog (révision 1545) ++++ sope-gdl1/Oracle8/ChangeLog (copie de travail) +@@ -1,3 +1,10 @@ ++2007-10-19 Ludovic Marcotte ++ ++ * We call OCITerminate() in OracleAdaptorChannel: ++ -closeChannel: ++ * Some formatting cleanups. ++ ++ + 2007-10-05 Ludovic Marcotte + + * Fixed otest wrt bundle name. +Index: sope-gdl1/Oracle8/OracleAdaptorChannel.m +=================================================================== +--- sope-gdl1/Oracle8/OracleAdaptorChannel.m (révision 1545) ++++ sope-gdl1/Oracle8/OracleAdaptorChannel.m (copie de travail) +@@ -112,7 +112,7 @@ + // Oracle's doc says: "If you call OCIStmtFetch2() with the nrows parameter set to 0, this cancels the cursor." + if (OCIStmtFetch2(_current_stm, _oci_err, (ub4)0, (ub4)OCI_FETCH_NEXT, (sb4)0, (ub4)OCI_DEFAULT)) + { +- NSLog( @"Fetch cancellation failed"); ++ NSLog(@"Fetch cancellation failed"); + } + + [self _cleanup]; +@@ -131,8 +131,13 @@ + // We logoff from the database. + if (OCILogoff(_oci_ctx, _oci_err)) + { +- NSLog( @"FAILED: OCILogoff()"); ++ NSLog(@"FAILED: OCILogoff()"); + } ++ ++ if (OCITerminate(OCI_DEFAULT)) ++ { ++ NSLog(@"FAILED: OCITerminate()"); ++ } + } + } + +@@ -369,19 +374,19 @@ + (dvoid * (*)(dvoid *, dvoid *, size_t))0, + (void (*)(dvoid *, dvoid *)) 0 )) + { +- NSLog( @"FAILED: OCIInitialize()"); ++ NSLog(@"FAILED: OCIInitialize()"); + return NO; + } + + if (OCIEnvInit((OCIEnv **)&_oci_env, (ub4)OCI_DEFAULT, (size_t)0, (dvoid **)0)) + { +- NSLog( @"FAILED: OCIEnvInit()"); ++ NSLog(@"FAILED: OCIEnvInit()"); + return NO; + } + + if (OCIHandleAlloc((dvoid *)_oci_env, (dvoid *)&_oci_err, (ub4)OCI_HTYPE_ERROR, (size_t)0, (dvoid **)0)) + { +- NSLog( @"FAILED: OCIHandleAlloc() on errhp"); ++ NSLog(@"FAILED: OCIHandleAlloc() on errhp"); + return NO; + } + +@@ -398,7 +403,7 @@ + if (OCILogon(_oci_env, _oci_err, &_oci_ctx, (const OraText*)username, strlen(username), + (const OraText*)password, strlen(password), (const OraText*)database, strlen(database))) + { +- NSLog( @"FAILED: OCILogon(). username = %s password = %s" ++ NSLog(@"FAILED: OCILogon(). username = %s password = %s" + @" database = %s", username, password, database); + return NO; + } +Index: sope-mime/NGImap4/NGImap4Connection.m +=================================================================== +--- sope-mime/NGImap4/NGImap4Connection.m (révision 1545) ++++ sope-mime/NGImap4/NGImap4Connection.m (copie de travail) +@@ -381,7 +381,7 @@ + + if (debugCache) [self logWithFormat:@" no folders cached yet .."]; + +- result = [[self client] list:(onlyFetchInbox ? @"INBOX" : @"*") ++ result = [[self client] list:(onlyFetchInbox ? @"INBOX" : @"") + pattern:@"*"]; + if (![[result valueForKey:@"result"] boolValue]) { + [self errorWithFormat:@"Could not list mailbox hierarchy!"]; +Index: sope-mime/NGImap4/NGImap4ResponseParser.m +=================================================================== +--- sope-mime/NGImap4/NGImap4ResponseParser.m (révision 1545) ++++ sope-mime/NGImap4/NGImap4ResponseParser.m (copie de travail) +@@ -84,6 +84,8 @@ + static NSDictionary *_parseMultipartBody(NGImap4ResponseParser *self, + BOOL isBodyStructure); + ++static NSArray *_parseLanguages(); ++ + static NSString *_parseBodyString(NGImap4ResponseParser *self, + BOOL _convertString); + static NSString *_parseBodyDecodeString(NGImap4ResponseParser *self, +@@ -1627,6 +1629,29 @@ + return _parseBodyDecodeString(self, _convertString, NO /* no decode */); + } + ++static NSArray *_parseLanguages(NGImap4ResponseParser *self) { ++ NSMutableArray *languages; ++ NSString *language; ++ ++ languages = [NSMutableArray array]; ++ if (_la(self, 0) == '(') { ++ while (_la(self, 0) != ')') { ++ _consume(self,1); ++ language = _parseBodyString(self, YES); ++ if ([language length]) ++ [languages addObject: language]; ++ } ++ _consume(self,1); ++ } ++ else { ++ language = _parseBodyString(self, YES); ++ if ([language length]) ++ [languages addObject: language]; ++ } ++ ++ return languages; ++} ++ + static NSDictionary *_parseBodyParameterList(NGImap4ResponseParser *self) + { + NSMutableDictionary *list; +@@ -1734,10 +1759,11 @@ + *encoding, *bodysize; + NSDictionary *parameterList; + NSMutableDictionary *dict; ++ NSArray *languages; + + type = [_parseBodyString(self, YES) lowercaseString]; + _consumeIfMatch(self, ' '); +- subtype = _parseBodyString(self, YES); ++ subtype = [_parseBodyString(self, YES) lowercaseString]; + _consumeIfMatch(self, ' '); + parameterList = _parseBodyParameterList(self); + _consumeIfMatch(self, ' '); +@@ -1762,7 +1788,8 @@ + _consumeIfMatch(self, ' '); + [dict setObject:_parseBodyString(self, YES) forKey:@"lines"]; + } +- else if ([type isEqualToString:@"message"]) { ++ else if ([type isEqualToString:@"message"] ++ && [subtype isEqualToString:@"rfc822"]) { + if (_la(self, 0) != ')') { + _consumeIfMatch(self, ' '); + _consumeIfMatch(self, '('); +@@ -1805,14 +1832,9 @@ + forKey: @"disposition"]; + if (_la(self, 0) != ')') { + _consume(self,1); +- if (_la(self, 0) == '(') { +- [dict setObject: _parseBodyParameterList(self) +- forKey: @"language"]; +- } +- else { +- [dict setObject: _parseBodyString(self, YES) +- forKey: @"language"]; +- } ++ languages = _parseLanguages(self); ++ if ([languages count]) ++ [dict setObject: languages forKey: @"languages"]; + if (_la(self, 0) != ')') { + _consume(self,1); + [dict setObject: _parseBodyString(self, YES) +@@ -1829,6 +1851,7 @@ + static NSDictionary *_parseMultipartBody(NGImap4ResponseParser *self, + BOOL isBodyStructure) { + NSMutableArray *parts; ++ NSArray *languages; + NSString *kind; + NSMutableDictionary *dict; + +@@ -1854,14 +1877,9 @@ + forKey: @"disposition"]; + if (_la(self, 0) != ')') { + _consume(self,1); +- if (_la(self, 0) == '(') { +- [dict setObject: _parseBodyParameterList(self) +- forKey: @"language"]; +- } +- else { +- [dict setObject: _parseBodyString(self, YES) +- forKey: @"language"]; +- } ++ languages = _parseLanguages(self); ++ if ([languages count]) ++ [dict setObject: languages forKey: @"languages"]; + if (_la(self, 0) != ')') { + _consume(self,1); + [dict setObject: _parseBodyString(self, YES) +Index: sope-mime/NGMime/NGMimeBodyPart.m +=================================================================== +--- sope-mime/NGMime/NGMimeBodyPart.m (révision 1545) ++++ sope-mime/NGMime/NGMimeBodyPart.m (copie de travail) +@@ -31,18 +31,6 @@ + return 2; + } + +-static NGMimeType *defaultType = nil; +- +-+ (void)initialize { +- static BOOL isInitialized = NO; +- if (!isInitialized) { +- isInitialized = YES; +- +- defaultType = +- [[NGMimeType mimeType:@"text/plain; charset=us-ascii"] retain]; +- } +-} +- + + (id)bodyPartWithHeader:(NGHashMap *)_header { + return [[[self alloc] initWithHeader:_header] autorelease]; + } +@@ -156,13 +144,12 @@ + if (!Fields) + Fields = (NGMimeHeaderNames *)[NGMimePartParser headerFieldNames]; + +- + type = [self->header objectForKey:Fields->contentType]; + + if (![type isKindOfClass:[NGMimeType class]]) + type = [NGMimeType mimeType:[type stringValue]]; + +- return (type != nil ? type : (id)defaultType); ++ return type; + } + + - (NSString *)contentId { +Index: sope-mime/NGMime/NGMimeBodyParser.m +=================================================================== +--- sope-mime/NGMime/NGMimeBodyParser.m (révision 1545) ++++ sope-mime/NGMime/NGMimeBodyParser.m (copie de travail) +@@ -67,7 +67,10 @@ + if (_data == nil) return nil; + + ctype = [_part contentType]; +- ++ if (!ctype ++ && [_d respondsToSelector: @selector(parser:contentTypeOfPart:)]) ++ ctype = [_d parser: self contentTypeOfPart: _part]; ++ + if (![ctype isKindOfClass:[NGMimeType class]]) + ctype = [NGMimeType mimeType:[ctype stringValue]]; + +Index: sope-mime/NGMime/NGMimePartParser.h +=================================================================== +--- sope-mime/NGMime/NGMimePartParser.h (révision 1545) ++++ sope-mime/NGMime/NGMimePartParser.h (copie de travail) +@@ -117,6 +117,7 @@ + BOOL parserParseRawBodyDataOfPart:1; + BOOL parserBodyParserForPart:1; + BOOL parserDecodeBodyOfPart:1; ++ BOOL parserContentTypeOfPart:1; + } delegateRespondsTo; + + +@@ -275,6 +276,9 @@ + - (id)parser:(NGMimePartParser *)_parser + bodyParserForPart:(id)_part; + ++- (NGMimeType *)parser:(id)_parser ++ contentTypeOfPart:(id)_part; ++ + @end /* NSObject(NGMimePartParserDelegate) */ + + @interface NSObject(NGMimePartParser) +Index: sope-mime/NGMime/NGMimePartParser.m +=================================================================== +--- sope-mime/NGMime/NGMimePartParser.m (révision 1545) ++++ sope-mime/NGMime/NGMimePartParser.m (copie de travail) +@@ -1091,7 +1091,10 @@ + id bodyParser = nil; + + ctype = [_p contentType]; +- ++ if (!ctype ++ && self->delegateRespondsTo.parserContentTypeOfPart) ++ ctype = [self->delegate parser: self contentTypeOfPart: _p]; ++ + contentType = ([ctype isKindOfClass:[NGMimeType class]]) + ? ctype + : [NGMimeType mimeType:[ctype stringValue]]; +Index: sope-appserver/NGObjWeb/GNUmakefile.postamble +=================================================================== +--- sope-appserver/NGObjWeb/GNUmakefile.postamble (révision 1545) ++++ sope-appserver/NGObjWeb/GNUmakefile.postamble (copie de travail) +@@ -23,14 +23,20 @@ + + # install makefiles + +-after-install :: ++after-install :: $(INSTALL_ROOT_DIR)/$(GNUSTEP_MAKEFILES)/Additional/ngobjweb.make ++ ++ifneq ($(GNUSTEP_MAKE_VERSION),1.3.0) ++after-install :: $(INSTALL_ROOT_DIR)/$(GNUSTEP_MAKEFILES)/woapp.make $(INSTALL_ROOT_DIR)/$(GNUSTEP_MAKEFILES)/wobundle.make ++endif ++ ++$(INSTALL_ROOT_DIR)/$(GNUSTEP_MAKEFILES)/Additional/ngobjweb.make: ngobjweb.make + $(MKDIRS) $(INSTALL_ROOT_DIR)/$(GNUSTEP_MAKEFILES)/Additional/ + $(INSTALL_DATA) ngobjweb.make $(INSTALL_ROOT_DIR)/$(GNUSTEP_MAKEFILES)/Additional/ngobjweb.make + +-ifneq ($(GNUSTEP_MAKE_VERSION),1.3.0) +-after-install :: ++$(INSTALL_ROOT_DIR)/$(GNUSTEP_MAKEFILES)/woapp.make: woapp-gs.make + $(INSTALL_DATA) woapp-gs.make \ + $(INSTALL_ROOT_DIR)/$(GNUSTEP_MAKEFILES)/woapp.make ++ ++$(INSTALL_ROOT_DIR)/$(GNUSTEP_MAKEFILES)/wobundle.make: wobundle-gs.make + $(INSTALL_DATA) wobundle-gs.make \ + $(INSTALL_ROOT_DIR)/$(GNUSTEP_MAKEFILES)/wobundle.make +-endif +Index: sope-appserver/NGObjWeb/WOContext.m +=================================================================== +--- sope-appserver/NGObjWeb/WOContext.m (révision 1545) ++++ sope-appserver/NGObjWeb/WOContext.m (copie de travail) +@@ -64,11 +64,13 @@ + static BOOL testNSURLs = NO; + static BOOL newCURLStyle = NO; + static NSString *WOApplicationSuffix = nil; ++static NSURL *redirectURL = nil; + + + (void)initialize { + static BOOL didInit = NO; + NSUserDefaults *ud; + NSString *cn; ++ NSString *url; + + if (didInit) return; + +@@ -91,6 +93,9 @@ + debugCursor = [ud boolForKey:@"WODebugCursor"] ? 1 : 0; + debugComponentAwake = [ud boolForKey:@"WODebugComponentAwake"]; + WOApplicationSuffix = [[ud stringForKey:@"WOApplicationSuffix"] copy]; ++ url = [ud stringForKey:@"WOApplicationRedirectURL"]; ++ if (url != nil) ++ redirectURL = [NSURL URLWithString: url]; + } + + + (id)contextWithRequest:(WORequest *)_r { +@@ -503,6 +508,11 @@ + return nil; + } + ++ if (redirectURL) { ++ // Use URL from user defaults (WOApplicationRedirectURL) ++ return redirectURL; ++ } ++ + if ((serverURL = [rq headerForKey:@"x-webobjects-server-url"]) == nil) { + if ((host = [rq headerForKey:@"host"])) + serverURL = [@"http://" stringByAppendingString:host]; +Index: sope-appserver/NGObjWeb/DynamicElements/WOHyperlinkInfo.m +=================================================================== +--- sope-appserver/NGObjWeb/DynamicElements/WOHyperlinkInfo.m (révision 1545) ++++ sope-appserver/NGObjWeb/DynamicElements/WOHyperlinkInfo.m (copie de travail) +@@ -216,6 +216,12 @@ + assocCount++; + } + } ++ if (count > 0) { ++ if ((self->isAbsolute = OWGetProperty(_config, @"absolute"))) { ++ count--; ++ assocCount++; ++ } ++ } + + self->rest = _config; + +Index: sope-appserver/NGObjWeb/DynamicElements/_WOComplexHyperlink.m +=================================================================== +--- sope-appserver/NGObjWeb/DynamicElements/_WOComplexHyperlink.m (révision 1545) ++++ sope-appserver/NGObjWeb/DynamicElements/_WOComplexHyperlink.m (copie de travail) +@@ -40,6 +40,7 @@ + WOAssociation *string; + WOAssociation *target; + WOAssociation *disabled; ++ WOAssociation *isAbsolute; + WOElement *template; + + /* new in WO4: */ +@@ -359,6 +360,7 @@ + { + if ((self = [super initWithName:_name hyperlinkInfo:_info template:_t])) { + self->href = _info->href; ++ self->isAbsolute = _info->isAbsolute; + } + return self; + } +@@ -374,6 +376,9 @@ + // TODO: we need a binding to disable rewriting! + NSRange r; + ++ if ([[self->isAbsolute valueInContext:_ctx] boolValue] == YES) ++ return NO; ++ + r = [_s rangeOfString:@":"]; + if (r.length == 0) + return YES; +Index: sope-appserver/NGObjWeb/DynamicElements/WOHyperlinkInfo.h +=================================================================== +--- sope-appserver/NGObjWeb/DynamicElements/WOHyperlinkInfo.h (révision 1545) ++++ sope-appserver/NGObjWeb/DynamicElements/WOHyperlinkInfo.h (copie de travail) +@@ -41,7 +41,8 @@ + WOAssociation *pageName; + WOAssociation *actionClass; + WOAssociation *directActionName; +- ++ WOAssociation *isAbsolute; ++ + BOOL sidInUrl; + + /* 'ivar' associations */ +Index: sope-appserver/NGObjWeb/WOHttpAdaptor/WOHttpTransaction.m +=================================================================== +--- sope-appserver/NGObjWeb/WOHttpAdaptor/WOHttpTransaction.m (révision 1545) ++++ sope-appserver/NGObjWeb/WOHttpAdaptor/WOHttpTransaction.m (copie de travail) +@@ -31,6 +31,7 @@ + #include + #include + #include ++#include + #include "common.h" + + #include +@@ -1016,6 +1017,12 @@ + - (void)parser:(NGMimePartParser *)_parser didParseHeader:(NGHashMap *)_header { + } + ++- (NGMimeType *)parser:(id)_parser ++ contentTypeOfPart:(id)_part ++{ ++ return [NGMimeType mimeType: @"text/plain; charset=utf-8"]; ++} ++ + @end /* WOHttpAdaptor */ + + @implementation WOCoreApplication(SimpleParserSelection) diff --git a/SoObjects/Mailer/SOGoMailAccount.m b/SoObjects/Mailer/SOGoMailAccount.m index eea913c2..f39aa7f6 100644 --- a/SoObjects/Mailer/SOGoMailAccount.m +++ b/SoObjects/Mailer/SOGoMailAccount.m @@ -185,6 +185,7 @@ static BOOL useAltNamespace = NO; rawFolders = [[self imap4Connection] allFoldersForURL: [self imap4URL]]; +#warning FIXME: the folder names should be prefixed mainFolders = [NSArray arrayWithObjects: inboxFolderName, draftsFolderName, sentFolder, trashFolder, nil]; newFolders = [NSMutableArray arrayWithArray: rawFolders]; diff --git a/SoObjects/Mailer/SOGoMailFolder.h b/SoObjects/Mailer/SOGoMailFolder.h index 89d8c68d..3cd98c20 100644 --- a/SoObjects/Mailer/SOGoMailFolder.h +++ b/SoObjects/Mailer/SOGoMailFolder.h @@ -43,25 +43,29 @@ NSDictionary *mailboxACL; } +- (NSString *) absoluteImap4Name; + /* messages */ -- (NSArray *)fetchUIDsMatchingQualifier:(id)_q sortOrdering:(id)_so; -- (NSArray *)fetchUIDs:(NSArray *)_uids parts:(NSArray *)_parts; +- (NSArray *) fetchUIDsMatchingQualifier: (id)_q sortOrdering: (id) _so; +- (NSArray *) fetchUIDs: (NSArray *) _uids parts: (NSArray *) _parts; -- (NSException *)postData:(NSData *)_data flags:(id)_flags; +- (NSException *) postData: (NSData *) _data flags: (id) _flags; -- (NSException *)expunge; +- (NSException *) expunge; /* flags */ -- (NSException *)addFlagsToAllMessages:(id)_f; +- (NSException *) addFlagsToAllMessages: (id) _f; /* folder type */ -- (NSString *)outlookFolderClass; +- (NSString *) outlookFolderClass; - (NSArray *) subfolders; -- (NSArray *) subfoldersURL; + +- (NSArray *) allFolderPaths; +- (NSArray *) allFolderURLs; @end diff --git a/SoObjects/Mailer/SOGoMailFolder.m b/SoObjects/Mailer/SOGoMailFolder.m index 892a663c..bf277fbb 100644 --- a/SoObjects/Mailer/SOGoMailFolder.m +++ b/SoObjects/Mailer/SOGoMailFolder.m @@ -106,6 +106,16 @@ static BOOL useAltNamespace = NO; return [nameInContainer substringFromIndex: 6]; } +- (NSString *) absoluteImap4Name +{ + NSString *name; + + name = [[self imap4URL] path]; + if (![name hasSuffix: @"/"]) + name = [name stringByAppendingString: @"/"]; + + return name; +} - (NSMutableString *) imap4URLString { @@ -129,25 +139,45 @@ static BOOL useAltNamespace = NO; return [[self imap4Connection] subfoldersForURL: [self imap4URL]]; } -- (NSArray *) subfoldersURL +- (NSArray *) allFolderPaths +{ + NSMutableArray *deepSubfolders; + NSEnumerator *folderNames; + NSArray *result; + NSString *currentFolderName, *prefix; + + deepSubfolders = [NSMutableArray new]; + [deepSubfolders autorelease]; + + prefix = [self absoluteImap4Name]; + + result = [[self mailAccountFolder] allFolderPaths]; + folderNames = [result objectEnumerator]; + while ((currentFolderName = [folderNames nextObject])) + if ([currentFolderName hasPrefix: prefix]) + [deepSubfolders addObject: currentFolderName]; + [deepSubfolders sortUsingSelector: @selector (compare:)]; + + return deepSubfolders; +} + +- (NSArray *) allFolderURLs { NSURL *selfURL, *currentURL; NSMutableArray *subfoldersURL; NSEnumerator *subfolders; - NSString *selfPath, *currentFolder; + NSString *currentFolder; subfoldersURL = [NSMutableArray array]; selfURL = [self imap4URL]; - selfPath = [selfURL path]; - subfolders = [[self subfolders] objectEnumerator]; + subfolders = [[self allFolderPaths] objectEnumerator]; currentFolder = [subfolders nextObject]; while (currentFolder) { currentURL = [[NSURL alloc] initWithScheme: [selfURL scheme] host: [selfURL host] - path: [selfPath stringByAppendingPathComponent: - currentFolder]]; + path: currentFolder]; [currentURL autorelease]; [subfoldersURL addObject: currentURL]; currentFolder = [subfolders nextObject]; diff --git a/SoObjects/SOGo/SOGoContentObject.m b/SoObjects/SOGo/SOGoContentObject.m index 255db3b6..00ed0779 100644 --- a/SoObjects/SOGo/SOGoContentObject.m +++ b/SoObjects/SOGo/SOGoContentObject.m @@ -382,6 +382,8 @@ } if ([containerAcls containsObject: SOGoRole_ObjectReader]) [acls addObject: SOGoRole_ObjectViewer]; + if ([containerAcls containsObject: SOGoRole_ObjectEditor]) + [acls addObject: SOGoRole_ObjectEditor]; } return acls; diff --git a/SoObjects/SOGo/SOGoFolder.m b/SoObjects/SOGo/SOGoFolder.m index 28697447..4ff6d1e2 100644 --- a/SoObjects/SOGo/SOGoFolder.m +++ b/SoObjects/SOGo/SOGoFolder.m @@ -259,23 +259,24 @@ static NSString *defaultUserID = @""; - (void) sendFolderAdvisoryTemplate: (NSString *) template { - NSString *language, *pageName; + NSString *pageName; SOGoUser *user; SOGoFolderAdvisory *page; - WOApplication *app; - user = [SOGoUser userWithLogin: [[context activeUser] login] roles: nil]; - language = [user language]; + user = [context activeUser]; pageName = [NSString stringWithFormat: @"SOGoFolder%@%@Advisory", - language, template]; + [user language], template]; - app = [WOApplication application]; - page = [app pageWithName: pageName inContext: context]; + page = [[WOApplication application] pageWithName: pageName + inContext: context]; [page setFolderObject: self]; - [page setRecipientUID: [[context activeUser] login]]; + [page setRecipientUID: [user login]]; [page send]; } + +// if (!result) [self sendFolderAdvisoryTemplate: @"Addition"]; + - (BOOL) create { NSException *result; @@ -284,8 +285,6 @@ static NSString *defaultUserID = @""; withName: displayName atPath: ocsPath]; - if (!result) [self sendFolderAdvisoryTemplate: @"Addition"]; - return (result == nil); } @@ -302,11 +301,11 @@ static NSString *defaultUserID = @""; else error = [[self folderManager] deleteFolderAtPath: ocsPath]; - if (!error) [self sendFolderAdvisoryTemplate: @"Removal"]; - return error; } +// if (!error) [self sendFolderAdvisoryTemplate: @"Removal"]; + - (void) renameTo: (NSString *) newName { GCSChannelManager *cm; diff --git a/UI/MailerUI/English.lproj/Localizable.strings b/UI/MailerUI/English.lproj/Localizable.strings index cf14bf58..2574e487 100644 --- a/UI/MailerUI/English.lproj/Localizable.strings +++ b/UI/MailerUI/English.lproj/Localizable.strings @@ -221,3 +221,8 @@ = "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!"; + +/* Message editing */ +"error_validationfailed" = "Validation failed"; +"error_missingsubject" = "Subject is missing"; +"error_missingrecipients" = "No recipients specified"; diff --git a/UI/MailerUI/French.lproj/Localizable.strings b/UI/MailerUI/French.lproj/Localizable.strings index b68ab6bb..6c805eaa 100644 --- a/UI/MailerUI/French.lproj/Localizable.strings +++ b/UI/MailerUI/French.lproj/Localizable.strings @@ -222,3 +222,8 @@ = "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."; + +/* Message editing */ +"error_validationfailed" = "Message invalide"; +"error_missingsubject" = "- le sujet est manquant"; +"error_missingrecipients" = "- aucun destinataire spécifié"; diff --git a/UI/MailerUI/German.lproj/Localizable.strings b/UI/MailerUI/German.lproj/Localizable.strings index 31b91fe6..40d826d2 100644 --- a/UI/MailerUI/German.lproj/Localizable.strings +++ b/UI/MailerUI/German.lproj/Localizable.strings @@ -205,3 +205,8 @@ = "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!"; + +/* Message editing */ +"error_validationfailed" = "Validation failed"; +"error_missingsubject" = "Subject is missing"; +"error_missingrecipients" = "No recipients specified"; diff --git a/UI/MailerUI/UIxMailActions.m b/UI/MailerUI/UIxMailActions.m index 7b6d9e13..4e962e43 100644 --- a/UI/MailerUI/UIxMailActions.m +++ b/UI/MailerUI/UIxMailActions.m @@ -20,6 +20,7 @@ * Boston, MA 02111-1307, USA. */ +#import #import #import @@ -221,4 +222,111 @@ return response; } +- (WOResponse *) _addLabel: (unsigned int) number +{ + WOResponse *response; + SOGoMailObject *co; + NSException *error; + NSArray *flags; + + co = [self clientObject]; + flags = [NSArray arrayWithObject: + [NSString stringWithFormat: @"$Label%u", number]]; + error = [co addFlags: flags]; + if (error) + response = (WOResponse *) error; + else + response = [self responseWith204]; + + return response; +} + +- (WOResponse *) _removeLabel: (unsigned int) number +{ + WOResponse *response; + SOGoMailObject *co; + NSException *error; + NSArray *flags; + + co = [self clientObject]; + flags = [NSArray arrayWithObject: + [NSString stringWithFormat: @"$Label%u", number]]; + error = [co removeFlags: flags]; + if (error) + response = (WOResponse *) error; + else + response = [self responseWith204]; + + return response; +} + +- (WOResponse *) addLabel1Action +{ + return [self _addLabel: 1]; +} + +- (WOResponse *) addLabel2Action +{ + return [self _addLabel: 2]; +} + +- (WOResponse *) addLabel3Action +{ + return [self _addLabel: 3]; +} + +- (WOResponse *) addLabel4Action +{ + return [self _addLabel: 4]; +} + +- (WOResponse *) addLabel5Action +{ + return [self _addLabel: 5]; +} + +- (WOResponse *) removeLabel1Action +{ + return [self _removeLabel: 1]; +} + +- (WOResponse *) removeLabel2Action +{ + return [self _removeLabel: 2]; +} + +- (WOResponse *) removeLabel3Action +{ + return [self _removeLabel: 3]; +} + +- (WOResponse *) removeLabel4Action +{ + return [self _removeLabel: 4]; +} + +- (WOResponse *) removeLabel5Action +{ + return [self _removeLabel: 5]; +} + +- (WOResponse *) removeAllLabelsAction +{ + WOResponse *response; + SOGoMailObject *co; + NSException *error; + NSArray *flags; + + co = [self clientObject]; + flags = [NSArray arrayWithObjects: @"$Label1", @"$Label2", @"$Label3", + @"$Label4", @"$Label5", nil]; + error = [co removeFlags: flags]; + if (error) + response = (WOResponse *) error; + else + response = [self responseWith204]; + + return response; +} + @end diff --git a/UI/MailerUI/UIxMailFolderActions.m b/UI/MailerUI/UIxMailFolderActions.m index ade6ed8d..c78fade8 100644 --- a/UI/MailerUI/UIxMailFolderActions.m +++ b/UI/MailerUI/UIxMailFolderActions.m @@ -265,7 +265,7 @@ { [co flushMailCaches]; connection = [co imap4Connection]; - subfolders = [[co subfoldersURL] objectEnumerator]; + subfolders = [[co allFolderURLs] objectEnumerator]; currentURL = [subfolders nextObject]; while (currentURL) { diff --git a/UI/MailerUI/UIxMailListView.m b/UI/MailerUI/UIxMailListView.m index e004eae9..e2cb26da 100644 --- a/UI/MailerUI/UIxMailListView.m +++ b/UI/MailerUI/UIxMailListView.m @@ -534,6 +534,23 @@ static int attachmentFlagSize = 8096; return [self redirectToLocation:@"view"]; } +- (NSString *) msgLabels +{ + NSMutableArray *labels; + NSEnumerator *flags; + NSString *currentFlag; + + labels = [NSMutableArray new]; + [labels autorelease]; + + flags = [[message objectForKey: @"flags"] objectEnumerator]; + while ((currentFlag = [flags nextObject])) + if ([currentFlag hasPrefix: @"$label"]) + [labels addObject: [currentFlag substringFromIndex: 1]]; + + return [labels componentsJoinedByString: @" "]; +} + @end /* UIxMailListView */ diff --git a/UI/MailerUI/product.plist b/UI/MailerUI/product.plist index 083bbe40..6f269fb3 100644 --- a/UI/MailerUI/product.plist +++ b/UI/MailerUI/product.plist @@ -255,6 +255,61 @@ actionClass = "UIxMailActions"; actionName = "markMessageRead"; }; + addLabel1 = { + protectedBy = "View"; + actionClass = "UIxMailActions"; + actionName = "addLabel1"; + }; + addLabel2 = { + protectedBy = "View"; + actionClass = "UIxMailActions"; + actionName = "addLabel2"; + }; + addLabel3 = { + protectedBy = "View"; + actionClass = "UIxMailActions"; + actionName = "addLabel3"; + }; + addLabel4 = { + protectedBy = "View"; + actionClass = "UIxMailActions"; + actionName = "addLabel4"; + }; + addLabel5 = { + protectedBy = "View"; + actionClass = "UIxMailActions"; + actionName = "addLabel5"; + }; + removeLabel1 = { + protectedBy = "View"; + actionClass = "UIxMailActions"; + actionName = "removeLabel1"; + }; + removeLabel2 = { + protectedBy = "View"; + actionClass = "UIxMailActions"; + actionName = "removeLabel2"; + }; + removeLabel3 = { + protectedBy = "View"; + actionClass = "UIxMailActions"; + actionName = "removeLabel3"; + }; + removeLabel4 = { + protectedBy = "View"; + actionClass = "UIxMailActions"; + actionName = "removeLabel4"; + }; + removeLabel5 = { + protectedBy = "View"; + actionClass = "UIxMailActions"; + actionName = "removeLabel5"; + }; + removeAllLabels = { + protectedBy = "View"; + actionClass = "UIxMailActions"; + actionName = "removeAllLabels"; + }; }; }; diff --git a/UI/MainUI/product.plist b/UI/MainUI/product.plist index 11e28282..9c0bba20 100644 --- a/UI/MainUI/product.plist +++ b/UI/MainUI/product.plist @@ -34,6 +34,8 @@ protectedBy = "Access Object"; defaultRoles = { "Access Object" = ( "Owner", "ObjectViewer" ); + "Access Contents Information" = ( "Owner", "ObjectViewer" ); + "Change Images And Files" = ( "Owner", "ObjectEditor" ); }; }; SOGoFolder = { diff --git a/UI/Templates/ContactsUI/UIxContactsFilterPanel.wox b/UI/Templates/ContactsUI/UIxContactsFilterPanel.wox index 8e92f86d..8f771ded 100644 --- a/UI/Templates/ContactsUI/UIxContactsFilterPanel.wox +++ b/UI/Templates/ContactsUI/UIxContactsFilterPanel.wox @@ -6,7 +6,7 @@ xmlns:label="OGo:label" >