diff --git a/ChangeLog b/ChangeLog index 5bbf88329..9287d1755 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2007-06-28 Wolfgang Sourdeau + + * UI/MailerUI/UIxMailListView.m ([UIxMailListView + -defaultSortKey]): default sort following the messages arrival + instead of their date. + ([-isSortedDescending]): removed method. + ([-imap4SortOrdering]): use the "asc" url parameter instead of + "desc" to determine the ordering. + (general): the template no longer use the UIxSortableTableHeader + components. + 2007-06-27 Wolfgang Sourdeau * UI/MailerUI/UIxMailListView.m ([UIxMailListView -sleep]): diff --git a/UI/MailerUI/UIxMailListView.h b/UI/MailerUI/UIxMailListView.h index 7d7fd458a..fddbfea8b 100644 --- a/UI/MailerUI/UIxMailListView.h +++ b/UI/MailerUI/UIxMailListView.h @@ -38,11 +38,9 @@ NSTimeZone *userTimeZone; } -- (NSString *)defaultSortKey; -- (NSString *)imap4SortKey; -- (NSString *)imap4SortOrdering; - -- (BOOL)isSortedDescending; +- (NSString *) defaultSortKey; +- (NSString *) imap4SortKey; +- (NSString *) imap4SortOrdering; @end diff --git a/UI/MailerUI/UIxMailListView.m b/UI/MailerUI/UIxMailListView.m index 3ae8d9d33..b63b740c1 100644 --- a/UI/MailerUI/UIxMailListView.m +++ b/UI/MailerUI/UIxMailListView.m @@ -175,7 +175,7 @@ static int attachmentFlagSize = 8096; /* Note: see SOGoMailManager.m for allowed IMAP4 keys */ static NSArray *keys = nil; if (keys == nil) { - keys = [[NSArray alloc] initWithObjects: + keys = [[NSArray alloc] initWithObjects: @"UID", @"FLAGS", @"ENVELOPE", @"RFC822.SIZE", nil]; } return keys; @@ -183,39 +183,29 @@ static int attachmentFlagSize = 8096; - (NSString *) defaultSortKey { - return @"DATE"; + return @"ARRIVAL"; } - (NSString *) imap4SortKey { NSString *sort; - sort = [[[self context] request] formValueForKey:@"sort"]; + sort = [[context request] formValueForKey: @"sort"]; - if ([sort length] == 0) + if (![sort length]) sort = [self defaultSortKey]; return [sort uppercaseString]; } -- (BOOL) isSortedDescending -{ - NSString *desc; - - desc = [[[self context] request] formValueForKey:@"desc"]; - - return ((desc) - ? [desc boolValue] - : YES); -} - - (NSString *) imap4SortOrdering { - NSString *sort; + NSString *sort, *ascending; sort = [self imap4SortKey]; - if ([self isSortedDescending]) + ascending = [[context request] formValueForKey: @"asc"]; + if (![ascending boolValue]) sort = [@"REVERSE " stringByAppendingString: sort]; return sort; @@ -232,9 +222,9 @@ static int attachmentFlagSize = 8096; { if (!sortedUIDs) { - sortedUIDs + sortedUIDs = [[self clientObject] fetchUIDsMatchingQualifier: qualifier - sortOrdering: [self imap4SortOrdering]]; + sortOrdering: [self imap4SortOrdering]]; [sortedUIDs retain]; } @@ -336,8 +326,8 @@ static int attachmentFlagSize = 8096; /* only need to restrict if we have a lot */ uids = [uids subarrayWithRange:r]; - msgs = [[self clientObject] fetchUIDs:uids parts: [self fetchKeys]]; - messages = [[msgs valueForKey:@"fetch"] retain]; + msgs = [[self clientObject] fetchUIDs: uids parts: [self fetchKeys]]; + messages = [[msgs valueForKey: @"fetch"] retain]; return messages; } @@ -422,25 +412,26 @@ static int attachmentFlagSize = 8096; { NSString *uid; - if ((uid = [[[self context] request] formValueForKey:@"uid"]) == nil) + if ((uid = [[context request] formValueForKey: @"uid"]) == nil) return nil; - return [[self clientObject] lookupName:uid inContext:[self context] - acquire:NO]; + return [[self clientObject] lookupName: uid + inContext: context + acquire: NO]; } /* actions */ - (BOOL) isJavaScriptRequest { - return [[[[self context] request] formValueForKey:@"jsonly"] boolValue]; + return [[[context request] formValueForKey:@"jsonly"] boolValue]; } - (id) javaScriptOK { WOResponse *r; - r = [[self context] response]; + r = [context response]; [r setStatus:200 /* OK */]; return r; } @@ -501,7 +492,7 @@ static int attachmentFlagSize = 8096; WORequest *request; NSString *specificMessage, *searchCriteria, *searchValue; - request = [[self context] request]; + request = [context request]; [[self clientObject] flushMailCaches]; diff --git a/UI/WebServerResources/MailerUI.css b/UI/WebServerResources/MailerUI.css index 0580941d7..98d15c6b3 100644 --- a/UI/WebServerResources/MailerUI.css +++ b/UI/WebServerResources/MailerUI.css @@ -494,21 +494,25 @@ TABLE#messageList THEAD TABLE#messageList TD { height: 1.2em; } +TD#messageFlagHeader, TABLE#messageList TD.messageFlagColumn { width: 1em; text-align: center; } +TD#subjectHeader, TABLE#messageList TD.tbtv_subject_headercell, TABLE#messageList td.mailer_unreadmailsubject, TABLE#messageList td.mailer_readmailsubject { width: 40%; min-width: 40%; } +TD#fromHeader, TABLE#messageList TD.tbtv_from_headercell, TABLE#messageList TD.messageAddressColumn { width: 35%; overflow: hidden; } +TD#dateHeader, TABLE#messageList TD.tbtv_date_headercell, TABLE#messageList TD.messageDateColumn { width: 25%; diff --git a/UI/WebServerResources/MailerUI.js b/UI/WebServerResources/MailerUI.js index d4f0264e8..cee5a84d4 100644 --- a/UI/WebServerResources/MailerUI.js +++ b/UI/WebServerResources/MailerUI.js @@ -386,6 +386,7 @@ function onMailboxTreeItemClick(event) { topNode.selectedEntry = this; search = {}; + sorting = {}; $("searchValue").value = ""; initCriteria(); @@ -423,7 +424,7 @@ function refreshMailbox() { return false; } -function openMailbox(mailbox, reload) { +function openMailbox(mailbox, reload, idx) { if (mailbox != currentMailbox || reload) { currentMailbox = mailbox; var url = ApplicationBaseURL + mailbox + "/view?noframe=1&desc=1"; @@ -458,6 +459,12 @@ function openMailbox(mailbox, reload) { if (searchValue && searchValue.length > 0) url += ("&search=" + search["criteria"] + "&value=" + searchValue); + var sortAttribute = sorting["attribute"]; + if (sortAttribute && sortAttribute.length > 0) + url += ("&sort=" + sorting["attribute"] + + "&asc=" + sorting["ascending"]); + if (idx) + url += "&idx=" + idx; document.messageListAjaxRequest = triggerAjaxRequest(url, messageListCallback, currentMessages[mailbox]); @@ -474,19 +481,7 @@ function openMailbox(mailbox, reload) { } function openMailboxAtIndex(event) { - var idx = this.getAttribute("idx"); - var url = ApplicationBaseURL + currentMailbox + "/view?noframe=1&idx=" + idx; - var searchValue = search["value"]; - if (searchValue && searchValue.length > 0) - url += ("&search=" + search["criteria"] - + "&value=" + searchValue); - - if (document.messageListAjaxRequest) { - document.messageListAjaxRequest.aborted = true; - document.messageListAjaxRequest.abort(); - } - document.messageListAjaxRequest - = triggerAjaxRequest(url, messageListCallback); + openMailbox(currentMailbox, true, this.getAttribute("idx")); preventDefault(event); } @@ -505,7 +500,26 @@ function messageListCallback(http) { row.select(); } configureMessageListEvents(); - configureSortableTableHeaders(); + if (sorting["attribute"] && sorting["attribute"].length > 0) { + var sortHeader; + if (sorting["attribute"] == "subject") + sortHeader = $("subjectHeader"); + else if (sorting["attribute"] == "from") + sortHeader = $("fromHeader"); + else if (sorting["attribute"] == "date") + sortHeader = $("dateHeader"); + else + sortHeader = null; + + if (sortHeader) { + var sortImage = createElement("img", "messageSortImage", "sortImage"); + sortHeader.insertBefore(sortImage, sortHeader.firstChild); + if (sorting["ascending"]) + sortImage.src = ResourcesURL + "/title_sortdown_12x12.png"; + else + sortImage.src = ResourcesURL + "/title_sortup_12x12.png"; + } + } } else log("messageListCallback: problem during ajax request (readyState = " + http.readyState + ", status = " + http.status + ")"); @@ -849,18 +863,25 @@ function expandUpperTree(node) { } function onHeaderClick(event) { - if (document.messageListAjaxRequest) { - document.messageListAjaxRequest.aborted = true; - document.messageListAjaxRequest.abort(); - } - var link = this.getAttribute("href"); - url = ApplicationBaseURL + currentMailbox + "/" + link; - if (link.indexOf("noframe=") < 0) - url += "&noframe=1"; + var headerId = this.getAttribute("id"); + var newSortAttribute; + if (headerId == "subjectHeader") + newSortAttribute = "subject"; + else if (headerId == "fromHeader") + newSortAttribute = "from"; + else if (headerId == "dateHeader") + newSortAttribute = "date"; + else + newSortAttribute = "arrival"; - log ("link: " + link); - document.messageListAjaxRequest - = triggerAjaxRequest(url, messageListCallback); + if (sorting["attribute"] == newSortAttribute) + sorting["ascending"] = !sorting["ascending"]; + else { + sorting["attribute"] = newSortAttribute; + sorting["ascending"] = true; + } + + openMailbox(currentMailbox, true); preventDefault(event); } @@ -955,11 +976,24 @@ var messageListData = function(type) { return msgIds; } +/* a model for a futur refactoring of the sortable table headers mechanism */ + +function configureMessageListHeaders(cells) { + for (var i = 0; i < cells.length; i++) { + var currentCell = $(cells[i]); + Event.observe(currentCell, "click", + onHeaderClick.bindAsEventListener(currentCell)); + Event.observe(currentCell, "mousedown", listRowMouseDownHandler); + } +} + function configureMessageListEvents() { var messageList = $("messageList"); if (messageList) { Event.observe(messageList, "mousedown", onMessageSelectionChange.bindAsEventListener(messageList)); + + configureMessageListHeaders(messageList.tHead.rows[0].cells); var cell = messageList.tHead.rows[1].cells[0]; if ($(cell).hasClassName("tbtv_navcell")) { var anchors = $(cell).childNodesWithTag("a"); @@ -976,7 +1010,7 @@ function configureMessageListEvents() { rows[i].dndGhost = messageListGhost; rows[i].dndDataForType = messageListData; document.DNDManager.registerSource(rows[i]); - + for (var j = 0; j < rows[i].cells.length; j++) { var cell = rows[i].cells[j]; Event.observe(cell, "mousedown", listRowMouseDownHandler); diff --git a/UI/WebServerResources/generic.css b/UI/WebServerResources/generic.css index 5ea9c2e1b..413af7758 100644 --- a/UI/WebServerResources/generic.css +++ b/UI/WebServerResources/generic.css @@ -390,7 +390,8 @@ td.tbtv_actcell TD.headerCell, TD.tbtv_headercell, TD.tbtv_navcell -{ background-color: #d4d0c8; +{ vertical-align: middle; + background-color: #d4d0c8; border-top: 1px solid #fff; border-left: 1px solid #fff; border-right: 2px solid #222; @@ -400,10 +401,13 @@ TD.tbtv_navcell TD.headerCell:active, TD.tbtv_headercell:active -{ background-color: #DCDAD5; - border: 1px solid #9c9a94; - -moz-border-bottom-colors: #9c9a94; - -moz-border-right-colors: #9c9a94; } +{ background-color: #dcdad5; + padding-top: 2px; + border-top: 1px solid #9c9a94; + border-left: 1px solid #9c9a94; + border-right: 2px solid #9c9a94; + border-bottom: 1px solid #9c9a94; + -moz-border-colors: #9c9a94 #000; } TD.headerCell SPAN, td.tbtv_headercell SPAN @@ -425,6 +429,7 @@ td.tbtv_headercell a:hover /* background-color: #C4C0B8; */ } +IMG.sortImage, TD.headerCell IMG.tbtv_sortcell, td.tbtv_headercell img.tbtv_sortcell { float: right; diff --git a/UI/WebServerResources/generic.js b/UI/WebServerResources/generic.js index 1a791bc67..7eb273f25 100644 --- a/UI/WebServerResources/generic.js +++ b/UI/WebServerResources/generic.js @@ -30,6 +30,7 @@ var queryParameters; var activeAjaxRequests = 0; var menus = new Array(); var search = {}; +var sorting = {}; var weekStartIsMonday = true; @@ -108,9 +109,13 @@ function createElement(tagName, id, classes, attributes, htmlAttributes, var newElement = $(document.createElement(tagName)); if (id) newElement.setAttribute("id", id); - if (classes) - for (var i = 0; i < classes.length; i++) - newElement.addClassName(classes[i]); + if (classes) { + if (typeof(classes) == "string") + newElement.addClassName(classes); + else + for (var i = 0; i < classes.length; i++) + newElement.addClassName(classes[i]); + } if (attributes) for (var i in attributes) newElement[i] = attributes[i]; @@ -977,7 +982,7 @@ function unsubscribeFromFolder(folder, refreshCallback, refreshCallbackData) { } function listRowMouseDownHandler(event) { - preventDefault(event); + preventDefault(event); } /* tabs */ @@ -1266,7 +1271,7 @@ function onPreferencesClick(event) { w.opener = window; w.focus(); - event.preventDefault(); + preventDefault(event); } function configureLinkBanner() {