#72282 fix the "watched threads" crasher, again

#62455 make sure double clicking on a cell in a column that is a cycler doesn't open the message in a new window

#72665, #73888
treat the thread unread and thread total columns like all the other columns.
allow the user to persist their hidden attribuyte.
don't hide / show them when switching between threaded and nonthreaded views.
All that's left is to hide those columns by default.

#72252 fix sort indicator problems

#72250 sorts should default to ascending

sr=bienvenu
This commit is contained in:
sspitzer%netscape.com 2001-04-03 06:13:38 +00:00
parent d6b514f4c5
commit 09e7288510
6 changed files with 93 additions and 186 deletions

View File

@ -25,7 +25,6 @@
interface nsIMsgFolder;
interface nsIMsgWindow;
interface nsIDOMElement;
interface nsIMessenger;
interface nsIMsgDBHdr;
interface nsIMsgDBViewCommandUpdater;
@ -242,8 +241,6 @@ interface nsIMsgDBView : nsISupports
*/
boolean navigateStatus(in nsMsgNavigationTypeValue motion);
attribute nsIDOMElement sortedColumn;
readonly attribute nsIMsgFolder msgFolder;
nsMsgKey getKeyAt(in nsMsgViewIndex index);

View File

@ -564,28 +564,10 @@ function CreateDBView(msgFolder, viewType, viewFlags, sortType, sortOrder)
else
gDBView.supressMsgDisplay = false;
var colID = ConvertSortTypeToColumnID(gCurSortType);
if (colID) {
var column = document.getElementById(colID);
gDBView.sortedColumn = column;
}
ShowAppropriateColumns();
UpdateSortIndicators(gCurSortType, sortOrder);
PersistViewAttributesOnFolder();
}
function ShowAppropriateColumns()
{
if (gDBView && (gDBView.sortType == nsMsgViewSortType.byThread)) {
// don't hide them when sorted by thread
SetHiddenAttributeOnThreadOnlyColumns("");
}
else {
// hide them when not sorted by thread
SetHiddenAttributeOnThreadOnlyColumns("true");
}
}
function SetViewFlags(viewFlags)
{
if (!gDBView) return;

View File

@ -38,22 +38,23 @@ function ThreadPaneOnClick(event)
HandleColumnClick(t.id);
}
else if (event.detail == 2 && t.localName == "outlinerbody") {
ThreadPaneDoubleClick();
var row = new Object;
var colID = new Object;
var childElt = new Object;
var outliner = GetThreadOutliner();
// figure out what cell the click was in
outliner.boxObject.QueryInterface(Components.interfaces.nsIOutlinerBoxObject).getCellAt(event.clientX, event.clientY, row, colID, childElt);
// if the cell is in a "cycler" column
// don't open the message in a new window
var col = document.getElementById(colID.value);
if (col && col.getAttribute("cycler") != "true") {
ThreadPaneDoubleClick();
}
}
}
function SetHiddenAttributeOnThreadOnlyColumns(value)
{
// todo, cache these?
var totalCol = document.getElementById("totalCol");
var unreadCol = document.getElementById("unreadCol");
totalCol.setAttribute("hidden",value);
unreadCol.setAttribute("hidden",value);
}
function nsMsgDBViewCommandUpdater()
{}
@ -84,16 +85,21 @@ nsMsgDBViewCommandUpdater.prototype =
function HandleColumnClick(columnID)
{
// if they click on the "threadCol", we need to show the threaded-only columns
if ((columnID[0] == 't') && (columnID[1] == 'h')) {
SetHiddenAttributeOnThreadOnlyColumns(""); // this will show them
var sortType = ConvertColumnIDToSortType(columnID);
// if sortType is 0, this is an unsupported sort type
// return, since we can't sort by that column.
if (sortType == 0) {
return;
}
var dbview = GetDBView();
if (dbview.sortType == sortType) {
MsgReverseSortThreadPane();
}
else {
SetHiddenAttributeOnThreadOnlyColumns("true"); // this will hide them
MsgSortThreadPane(sortType);
}
ShowAppropriateColumns();
PersistViewAttributesOnFolder();
}
function PersistViewAttributesOnFolder()
@ -118,16 +124,12 @@ function MsgComposeDraftMessage()
function ThreadPaneDoubleClick()
{
var loadedFolder;
var messageArray;
var messageUri;
if (IsSpecialFolderSelected(MSG_FOLDER_FLAG_DRAFTS)) {
MsgComposeDraftMessage();
}
else if(IsSpecialFolderSelected(MSG_FOLDER_FLAG_TEMPLATES)) {
loadedFolder = GetLoadedMsgFolder();
messageArray = GetSelectedMessages();
var loadedFolder = GetLoadedMsgFolder();
var messageArray = GetSelectedMessages();
ComposeMessage(msgComposeType.Template, msgComposeFormat.Default, loadedFolder, messageArray);
}
else {
@ -203,20 +205,69 @@ function MsgSortByThread()
function MsgSortThreadPane(sortType)
{
gDBView.sort(sortType, nsMsgViewSortOrder.ascending);
ShowAppropriateColumns();
var dbview = GetDBView();
dbview.sort(sortType, nsMsgViewSortOrder.ascending);
UpdateSortIndicators(sortType, nsMsgViewSortOrder.ascending);
PersistViewAttributesOnFolder();
}
function MsgReverseSortThreadPane()
{
var dbview = GetDBView();
if (dbview.sortOrder == nsMsgViewSortOrder.ascending) {
MsgSortDescending();
}
else {
MsgSortAscending();
}
}
function MsgSortAscending()
{
gDBView.sort(gDBView.sortType, nsMsgViewSortOrder.ascending);
var dbview = GetDBView();
dbview.sort(dbview.sortType, nsMsgViewSortOrder.ascending);
UpdateSortIndicators(dbview.sortType, nsMsgViewSortOrder.ascending);
PersistViewAttributesOnFolder();
}
function MsgSortDescending()
{
gDBView.sort(gDBView.sortType, nsMsgViewSortOrder.descending);
var dbview = GetDBView();
dbview.sort(dbview.sortType, nsMsgViewSortOrder.descending);
UpdateSortIndicators(dbview.sortType, nsMsgViewSortOrder.descending);
PersistViewAttributesOnFolder();
}
function UpdateSortIndicators(sortType, sortOrder)
{
var colID = ConvertSortTypeToColumnID(sortType);
var sortedColumn;
// set the sort indicator on the column we are sorted by
if (colID) {
sortedColumn = document.getElementById(colID);
if (sortedColumn) {
if (sortOrder == nsMsgViewSortOrder.ascending) {
sortedColumn.setAttribute("sortDirection","ascending");
}
else {
sortedColumn.setAttribute("sortDirection","descending");
}
}
}
// remove the sort indicator from all the columns
// except the one we are sorted by
var currCol = GetThreadOutliner().firstChild;
while (currCol) {
while (currCol && currCol.localName != "outlinercol")
currCol = currCol.nextSibling;
if (currCol && (currCol != sortedColumn)) {
currCol.removeAttribute("sortDirection");
}
if (currCol)
currCol = currCol.nextSibling;
}
}
function IsSpecialFolderSelected(flags)

View File

@ -191,10 +191,12 @@ function searchOnLoad()
// hide the thread related columns. you can't thread search results
var threadCol = document.getElementById("threadCol");
threadCol.setAttribute("hidden","true");
SetHiddenAttributeOnThreadOnlyColumns("true");
var totalCol = document.getElementById("totalCol");
totalCol.setAttribute("hidden","true");
var unreadCol = document.getElementById("unreadCol");
unreadCol.setAttribute("hidden","true");
}
function searchOnUnload()
{
// unregister listeners

View File

@ -383,22 +383,6 @@ nsresult nsMsgDBView::FetchPriority(nsIMsgHdr *aHdr, PRUnichar ** aPriorityStrin
return NS_OK;
}
// call this AFTER calling ::Sort.
nsresult nsMsgDBView::UpdateSortUI(nsIDOMElement * aNewSortColumn)
{
if (mCurrentSortColumn && aNewSortColumn != mCurrentSortColumn)
mCurrentSortColumn->RemoveAttribute(NS_LITERAL_STRING("sortDirection"));
// set the new sort direction on the new sort column
mCurrentSortColumn = aNewSortColumn;
if (m_sortOrder == nsMsgViewSortOrder::ascending)
mCurrentSortColumn->SetAttribute(NS_LITERAL_STRING("sortDirection"), NS_LITERAL_STRING("ascending"));
else
mCurrentSortColumn->SetAttribute(NS_LITERAL_STRING("sortDirection"), NS_LITERAL_STRING("descending"));
return NS_OK;
}
nsresult nsMsgDBView::SaveSelection(nsMsgKeyArray *aMsgKeyArray)
{
if (!mOutlinerSelection)
@ -859,6 +843,9 @@ NS_IMETHODIMP nsMsgDBView::HasNextSibling(PRInt32 rowIndex, PRInt32 afterIndex,
NS_IMETHODIMP nsMsgDBView::GetLevel(PRInt32 index, PRInt32 *_retval)
{
if (!IsValidIndex(index))
return NS_MSG_INVALID_DBVIEW_INDEX;
if (m_viewFlags & nsMsgViewFlagsType::kThreadedDisplay)
*_retval = m_levels[index];
else
@ -997,98 +984,9 @@ NS_IMETHODIMP nsMsgDBView::ToggleOpenState(PRInt32 index)
NS_IMETHODIMP nsMsgDBView::CycleHeader(const PRUnichar * aColID, nsIDOMElement * aElement)
{
// if the header is a sortable column then we want to call Sort
// otherwise, we'll do something else =)
nsMsgViewSortTypeValue sortType = nsMsgViewSortType::bySubject;
nsMsgViewSortOrderValue sortOrder = nsMsgViewSortOrder::descending;
PRBool performSort = PR_TRUE;
nsAutoString sortOrderValue;
aElement->GetAttribute(NS_LITERAL_STRING("sortDirection"), sortOrderValue);
if (!sortOrderValue.IsEmpty() && sortOrderValue.Equals(NS_LITERAL_STRING("ascending")))
sortOrder = nsMsgViewSortOrder::ascending;
if ((aColID[0] != 't') && (aColID[1] != 'h')) {
m_viewFlags &= ~nsMsgViewFlagsType::kThreadedDisplay;
}
switch (aColID[0])
{
case 's':
if (aColID[1] == 'u') // sort the subject
{
sortType = nsMsgViewSortType::bySubject;
}
else if (aColID[1] == 'e') // sort by sender
{
if (mIsSpecialFolder)
sortType = nsMsgViewSortType::byRecipient;
else
sortType = nsMsgViewSortType::byAuthor;
}
else if (aColID[1] == 'i') // size
{
sortType = nsMsgViewSortType::bySize;
}
else
{
sortType = nsMsgViewSortType::byStatus;
}
break;
case 'u':
if (aColID[6] == 'B') // unreadButtonColHeader
{
sortType = nsMsgViewSortType::byUnread;
}
else // unreadCol
{
NS_ASSERTION(0,"fix this");
performSort = PR_FALSE;
}
break;
case 'd': // date
sortType = nsMsgViewSortType::byDate;
break;
case 'p': // priority
sortType = nsMsgViewSortType::byPriority;
break;
case 't': // thread column
if (aColID[1] == 'h') {
sortType = nsMsgViewSortType::byThread;
m_viewFlags |= nsMsgViewFlagsType::kThreadedDisplay;
}
else {
NS_ASSERTION(0,"fix this");
//sortType = nsMsgViewSortType::byTotal;
performSort = PR_FALSE;
}
break;
case 'f': // flagged
sortType = nsMsgViewSortType::byFlagged;
break;
default:
performSort = PR_FALSE;
break;
}
if (performSort)
{
// if we are already sorted by the same order, then toggle ascending / descending.
if (m_sortType == sortType)
{
if (sortOrder == nsMsgViewSortOrder::ascending)
sortOrder = nsMsgViewSortOrder::descending;
else
sortOrder = nsMsgViewSortOrder::ascending;
}
Sort(sortType, sortOrder);
UpdateSortUI(aElement);
} // if performSort
return NS_OK;
// let HandleColumnClick() in threadPane.js handle it
// since it will set / clear the sort indicators.
return NS_OK;
}
NS_IMETHODIMP nsMsgDBView::CycleCell(PRInt32 row, const PRUnichar *colID)
@ -1137,23 +1035,6 @@ NS_IMETHODIMP nsMsgDBView::PerformActionOnCell(const PRUnichar *action, PRInt32
return NS_OK;
}
NS_IMETHODIMP nsMsgDBView::GetSortedColumn(nsIDOMElement ** aColumn)
{
*aColumn = mCurrentSortColumn;
NS_IF_ADDREF(*aColumn);
return NS_OK;
}
NS_IMETHODIMP nsMsgDBView::SetSortedColumn(nsIDOMElement * aColumn)
{
if (!mCurrentSortColumn)
UpdateSortUI(aColumn);
mCurrentSortColumn = aColumn;
return NS_OK;
}
///////////////////////////////////////////////////////////////////////////
// end nsIOutlinerView Implementation Methods
///////////////////////////////////////////////////////////////////////////
@ -1697,7 +1578,6 @@ nsresult nsMsgDBView::DownloadFlaggedForOffline(nsIMsgWindow *window)
return rv;
}
// read/unread handling.
nsresult nsMsgDBView::ToggleReadByIndex(nsMsgViewIndex index)
{

View File

@ -113,10 +113,6 @@ protected:
nsresult FetchPriority(nsIMsgHdr *aHdr, PRUnichar ** aPriorityString);
nsresult CycleThreadedColumn(nsIDOMElement * aElement);
// toggles ascending/descending or adds the sort attribute
// also cleans up the attributes on the previously sorted column.
nsresult UpdateSortUI(nsIDOMElement * aNewSortColumn);
// Save and Restore Selection are a pair of routines you should
// use when performing an operation which is going to change the view
// and you want to remember the selection. (i.e. for sorting).
@ -266,7 +262,6 @@ protected:
nsMsgViewSortTypeValue m_sortType;
nsMsgViewSortOrderValue m_sortOrder;
nsMsgViewFlagsTypeValue m_viewFlags;
nsCOMPtr<nsIDOMElement> mCurrentSortColumn;
// I18N date formater service which we'll want to cache locally.
nsCOMPtr<nsIDateTimeFormat> mDateFormater;