2007-11-05 Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ * UI/MailPartViewers/UIxMailPartTextViewer.m
+ ([UIxMailPartTextViewer -flatContentAsString]): re-added
+ conversion of line-break to sequences of HTML "BR", with a fast
+ algorithm in C.
+
+ * UI/MailPartViewers/UIxMailPartViewer.m ([UIxMailPartViewer
+ -flatContentAsString]): simplified method now that we know
+ -[NSString stringWithData:usingEncodingNamed:] has a more robust
+ implementation.
+
+ * UI/MailerUI/UIxMailListView.m ([UIxMailListView
+ -showToAddress]): the answer is cached.
+
* UI/Common/UIxObjectActions.m ([UIxObjectActions +initialize]):
read "SOGoACLsSendEMailNotifications" from the user defaults to
determiner whether to send an email when a user is added or
- support for resizable columns in tables;
- improved support for multiple selection in tables and lists;
- improved IE7 and Safari support: attendees selector, email file attachments;
+- changed look of message composition window to Thunderbird 2.0;
- countless bugfixes;
0.9.0-20070824
- (void) setFrequency: (iCalRecurrenceFrequency) _frequency;
- (iCalRecurrenceFrequency) frequency;
+- (iCalRecurrenceFrequency) valueForFrequency: (NSString *) value;
- (void) setRepeatInterval: (int) _repeatInterval;
- (int) repeatInterval;
+- (void) setInterval: (NSString *) _interval;
+
- (void) setWeekStart: (iCalWeekDay) _weekStart;
- (iCalWeekDay) weekStart;
- (void)removeAllRecurrenceRules;
- (void)addToRecurrenceRules:(id)_rrule;
+- (void)setRecurrenceRules:(id)_rrule;
- (BOOL)hasRecurrenceRules;
- (NSArray *)recurrenceRules;
#import "UIxMailPartTextViewer.h"
+@interface NSString (SOGoMailUIExtension)
+
+- (NSString *) stringByConvertingCRLNToHTML;
+
+@end
+
+@implementation NSString (SOGoMailUIExtension)
+
+- (NSString *) stringByConvertingCRLNToHTML
+{
+ NSString *convertedString;
+ const char *oldString, *currentChar;
+ char *newString, *destChar;
+ unsigned int oldLength, length, delta;
+
+ oldString = [self cStringUsingEncoding: NSUTF8StringEncoding];
+ oldLength = [self lengthOfBytesUsingEncoding: NSUTF8StringEncoding];
+
+ length = oldLength;
+ newString = malloc (length + 500);
+ destChar = newString;
+ currentChar = oldString;
+ while (currentChar < (oldString + oldLength))
+ {
+ if (*currentChar != '\r')
+ {
+ if (*currentChar == '\n')
+ {
+ strcpy (destChar, "<br />");
+ destChar += 6;
+ delta = (destChar - newString);
+ if (delta > length)
+ {
+ length += 500;
+ newString = realloc (newString, length + 500);
+ destChar = newString + delta;
+ }
+ }
+ else
+ {
+ *destChar = *currentChar;
+ destChar++;
+ }
+ }
+ currentChar++;
+ }
+ *destChar = 0;
+
+ convertedString = [[NSString alloc] initWithBytes: newString
+ length: (destChar + 1 - newString)
+ encoding: NSUTF8StringEncoding];
+ [convertedString autorelease];
+ free (newString);
+
+ return convertedString;
+}
+
+@end
+
@implementation UIxMailPartTextViewer
- (NSString *) flatContentAsString
{
- NSMutableString *content;
NSString *superContent;
- content = [NSMutableString string];
superContent = [[super flatContentAsString] stringByEscapingHTMLString];
- [content appendString: [superContent stringByDetectingURLs]];
- return content;
+ return [[superContent stringByDetectingURLs] stringByConvertingCRLNToHTML];
}
@end /* UIxMailPartTextViewer */
{
charset = [[bodyInfo objectForKey:@"parameterList"]
objectForKey: @"charset"];
- charset = [charset lowercaseString];
- if (![charset length]
- || [charset isEqualToString: @"us-ascii"])
+ if ([charset length])
+ charset = [charset lowercaseString];
+ else
+ charset = @"us-ascii";
+ s = [NSString stringWithData: content usingEncodingNamed: charset];
+ if (![s length])
{
+ /* latin 1 is used as a 8bit fallback charset... but does this
+ encoding accept any byte from 0 to 255? */
s = [[NSString alloc] initWithData: content
encoding: NSISOLatin1StringEncoding];
[s autorelease];
}
- else
- {
- s = [NSString stringWithData: content
- usingEncodingNamed: charset];
- if (![s length])
- {
- /* latin 1 is used as a 8bit fallback charset... but does this
- encoding accept any byte from 0 to 255? */
- s = [[NSString alloc] initWithData: content
- encoding: NSISOLatin1StringEncoding];
- [s autorelease];
- }
- }
if (!s)
{
EOQualifier *qualifier;
SOGoDateFormatter *dateFormatter;
NSTimeZone *userTimeZone;
+ int folderType;
}
- (NSString *) defaultSortKey;
#import <EOControl/EOQualifier.h>
+#import <SoObjects/Mailer/SOGoDraftsFolder.h>
#import <SoObjects/Mailer/SOGoMailFolder.h>
#import <SoObjects/Mailer/SOGoMailObject.h>
+#import <SoObjects/Mailer/SOGoSentFolder.h>
#import <SoObjects/SOGo/NSArray+Utilities.h>
#import <SoObjects/SOGo/SOGoDateFormatter.h>
#import <SoObjects/SOGo/SOGoUser.h>
user = [context activeUser];
ASSIGN (dateFormatter, [user dateFormatterInContext: context]);
ASSIGN (userTimeZone, [user timeZone]);
+ folderType = 0;
}
return self;
- (BOOL) showToAddress
{
- NSString *ftype;
-
- ftype = [[self clientObject] valueForKey:@"outlookFolderClass"];
- return [ftype isEqual:@"IPF.Sent"];
+ SOGoMailFolder *co;
+
+ if (!folderType)
+ {
+ co = [self clientObject];
+ if ([co isKindOfClass: [SOGoSentFolder class]]
+ || [co isKindOfClass: [SOGoDraftsFolder class]])
+ folderType = 1;
+ else
+ folderType = -1;
+ }
+
+ return (folderType == 1);
}
/* title */
- (NSString *) messageRowStyleClass
{
- return [self isMessageDeleted]
- ? @"mailer_listcell_deleted"
- : @"mailer_listcell_regular";
+ NSString *rowClass;
+
+ rowClass = [self isMessageDeleted]? @"mailer_listcell_deleted" : @"mailer_listcell_regular";
+
+ if (![self isMessageRead])
+ rowClass = [rowClass stringByAppendingString: @" mailer_unreadmail"];
+
+ return rowClass;
}
- (NSString *) messageSubjectCellStyleClass
{
NSArray *flags;
- NSString *cellClass;
+ NSString *cellClass = @"messageSubjectColumn ";
flags = [[self message] valueForKey:@"flags"];
- if ([flags containsObject: @"seen"])
+ if ([flags containsObject: @"answered"])
{
- if ([flags containsObject: @"answered"])
- {
- if ([flags containsObject: @"$forwarded"])
- cellClass = @"mailer_forwardedrepliedmailsubject";
- else
- cellClass = @"mailer_repliedmailsubject";
- }
- else if ([flags containsObject: @"$forwarded"])
- cellClass = @"mailer_forwardedmailsubject";
+ if ([flags containsObject: @"$forwarded"])
+ cellClass = [cellClass stringByAppendingString: @"mailer_forwardedrepliedmailsubject"];
else
- cellClass = @"mailer_readmailsubject";
+ cellClass = [cellClass stringByAppendingString: @"mailer_repliedmailsubject"];
}
+ else if ([flags containsObject: @"$forwarded"])
+ cellClass = [cellClass stringByAppendingString: @"mailer_forwardedmailsubject"];
else
- cellClass = @"mailer_unreadmailsubject";
+ cellClass = [cellClass stringByAppendingString: @"mailer_readmailsubject"];
return cellClass;
-// return ([self isMessageRead]
-// ? @"mailer_readmailsubject"
-// : @"mailer_unreadmailsubject");
}
- (BOOL) hasMessageAttachment
padding-left: 20px !important;
}
-TD.mailer_unreadmailsubject
+TR.mailer_unreadmail TD
{
- background-image: url(icon-new.png) !important;
+ font-weight: bold !important;
+}
+
+TR.mailer_unreadmail TD.messageSubjectColumn
+{
+ background-image: url(icon-new.png);
background-repeat: no-repeat !important;
background-position: 0px 0px !important;
padding-left: 20px !important;
/* mail list DOM changes */
function markMailInWindow(win, msguid, markread) {
- var msgDiv;
-
- msgDiv = win.$("div_" + msguid);
- if (msgDiv) {
+ var row = win.$("row_" + msguid);
+ var subjectCell = win.$("div_" + msguid);
+ if (row && subjectCell) {
if (markread) {
- msgDiv.removeClassName("mailer_unreadmailsubject");
- msgDiv.addClassName("mailer_readmailsubject");
- msgDiv = win.$("unreaddiv_" + msguid);
- if (msgDiv)
- {
- msgDiv.setAttribute("class", "mailerUnreadIcon");
- msgDiv.setAttribute("id", "readdiv_" + msguid);
- msgDiv.setAttribute("src", ResourcesURL + "/icon_read.gif");
- msgDiv.setAttribute("onclick", "mailListMarkMessage(this,"
- + " 'markMessageUnread', " + msguid
- + ", false);"
- +" return false;");
- var title = msgDiv.getAttribute("title-markunread");
- if (title)
- msgDiv.setAttribute("title", title);
- }
+ row.removeClassName("mailer_unreadmail");
+ subjectCell.addClassName("mailer_readmailsubject");
+ var img = win.$("unreaddiv_" + msguid);
+ if (img) {
+ img.removeClassName("mailerUnreadIcon");
+ img.addClassName("mailerReadIcon");
+ img.setAttribute("id", "readdiv_" + msguid);
+ img.setAttribute("src", ResourcesURL + "/icon_read.gif");
+ var title = img.getAttribute("title-markunread");
+ if (title)
+ img.setAttribute("title", title);
+ }
}
else {
- msgDiv.removeClassName('mailer_readmailsubject');
- msgDiv.addClassName('mailer_unreadmailsubject');
- msgDiv = win.$("readdiv_" + msguid);
- if (msgDiv)
- {
- msgDiv.setAttribute("class", "mailerReadIcon");
- msgDiv.setAttribute("id", "unreaddiv_" + msguid);
- msgDiv.setAttribute("src", ResourcesURL + "/icon_unread.gif");
- msgDiv.setAttribute("onclick", "mailListMarkMessage(this,"
- + " 'markMessageRead', " + msguid
- + ", true);"
- +" return false;");
- var title = msgDiv.getAttribute("title-markread");
- if (title)
- msgDiv.setAttribute("title", title);
- }
+ row.addClassName("mailer_unreadmail");
+ subjectCell.removeClassName('mailer_readmailsubject');
+ var img = win.$("readdiv_" + msguid);
+ if (img) {
+ img.removeClassName("mailerReadIcon");
+ img.addClassName("mailerUnreadIcon");
+ img.setAttribute("id", "unreaddiv_" + msguid);
+ img.setAttribute("src", ResourcesURL + "/icon_unread.gif");
+ var title = img.getAttribute("title-markread");
+ if (title)
+ img.setAttribute("title", title);
+ }
}
return true;
}
}
function mailListMarkMessage(event) {
- var http = createHTTPClient();
+ var msguid = this.id.split('_')[1];
+ var action;
+ var markread;
+ if ($(this).hasClassName('mailerUnreadIcon')) {
+ action = 'markMessageRead';
+ markread = true;
+ }
+ else {
+ action = 'markMessageUnread';
+ markread = false;
+ }
var url = ApplicationBaseURL + currentMailbox + "/" + msguid + "/" + action;
- if (http) {
- // TODO: add parameter to signal that we are only interested in OK
- http.open("POST", url, false /* not async */);
- http.send("");
- if (http.status != 200) {
- // TODO: refresh page?
- alert("Message Mark Failed: " + http.statusText);
- window.location.reload();
+ var data = { "window": window, "msguid": msguid, "markread": markread };
+ triggerAjaxRequest(url, mailListMarkMessageCallback, data);
+
+ preventDefault(event);
+ return false;
+}
+
+function mailListMarkMessageCallback(http) {
+ if (http.readyState == 4)
+ if (isHttpStatus204(http.status)) {
+ var data = http.callbackData;
+ markMailInWindow(data["window"], data["msguid"], data["markread"]);
}
else {
- markMailInWindow(window, msguid, markread);
+ alert("Message Mark Failed (" + http.status + "): " + http.statusText);
+ window.location.reload();
}
- }
- else {
- window.location.href = url;
- }
}
/* maillist row highlight */
var rowIds = messageList.getSelectedRowsId();
for (var i = 0; i < rowIds.length; i++) {
- var url, http;
+ var url;
var rowId = rowIds[i].substr(4);
var messageId = currentMailbox + "/" + rowId;
url = ApplicationBaseURL + messageId + "/trash";
var cachedMessage = getCachedMessage(idx);
+ markMailInWindow(window, idx, true);
if (cachedMessage == null) {
var url = (ApplicationBaseURL + currentMailbox + "/"
+ idx + "/view?noframe=1");
document.messageAjaxRequest
= triggerAjaxRequest(url, messageCallback, idx);
- markMailInWindow(window, idx, true);
} else {
var div = $('messageContent');
div.update(cachedMessage['text']);
Event.observe(cell, "dblclick", onMessageDoubleClick.bindAsEventListener(cell));
else if (j == 4) {
var img = cell.childNodesWithTag("img")[0];
- Event.observe(img, "click", mailListMarkMessage);
+ Event.observe(img, "click", mailListMarkMessage.bindAsEventListener(img));
}
}
}
var name = window.prompt(labels["Name :"], "");
if (name && name.length > 0) {
var folderID = document.menuTarget.getAttribute("dataname");
- var urlstr = URLForFolderID(folderID) + "/createFolder?name=" + name; log ("create " + urlstr);
+ var urlstr = URLForFolderID(folderID) + "/createFolder?name=" + name;
triggerAjaxRequest(urlstr, folderOperationCallback);
}
}