mirror of
https://github.com/rn10950/RetroZilla.git
synced 2024-11-14 03:30:17 +01:00
540 lines
15 KiB
JavaScript
540 lines
15 KiB
JavaScript
|
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||
|
* ***** BEGIN LICENSE BLOCK *****
|
||
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||
|
*
|
||
|
* The contents of this file are subject to the Mozilla Public License Version
|
||
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
||
|
* the License. You may obtain a copy of the License at
|
||
|
* http://www.mozilla.org/MPL/
|
||
|
*
|
||
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
||
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||
|
* for the specific language governing rights and limitations under the
|
||
|
* License.
|
||
|
*
|
||
|
* The Original Code is Mozilla Communicator client code, released
|
||
|
* March 31, 1998.
|
||
|
*
|
||
|
* The Initial Developer of the Original Code is
|
||
|
* Netscape Communications Corporation.
|
||
|
* Portions created by the Initial Developer are Copyright (C) 1998-1999
|
||
|
* the Initial Developer. All Rights Reserved.
|
||
|
*
|
||
|
* Contributor(s):
|
||
|
*
|
||
|
* Alternatively, the contents of this file may be used under the terms of
|
||
|
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||
|
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||
|
* of those above. If you wish to allow use of your version of this file only
|
||
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||
|
* use your version of this file under the terms of the MPL, indicate your
|
||
|
* decision by deleting the provisions above and replace them with the notice
|
||
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||
|
* the provisions above, a recipient may use your version of this file under
|
||
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
||
|
*
|
||
|
* ***** END LICENSE BLOCK ***** */
|
||
|
|
||
|
var gLastMessageUriToLoad = null;
|
||
|
var gThreadPaneCommandUpdater = null;
|
||
|
|
||
|
function ThreadPaneOnClick(event)
|
||
|
{
|
||
|
// we only care about button 0 (left click) events
|
||
|
if (event.button != 0) return;
|
||
|
|
||
|
// we are already handling marking as read and flagging
|
||
|
// in nsMsgDBView.cpp
|
||
|
// so all we need to worry about here is double clicks
|
||
|
// and column header.
|
||
|
//
|
||
|
// we get in here for clicks on the "treecol" (headers)
|
||
|
// and the "scrollbarbutton" (scrollbar buttons)
|
||
|
// we don't want those events to cause a "double click"
|
||
|
|
||
|
var t = event.originalTarget;
|
||
|
|
||
|
if (t.localName == "treecol") {
|
||
|
HandleColumnClick(t.id);
|
||
|
}
|
||
|
else if (t.localName == "treechildren") {
|
||
|
var row = new Object;
|
||
|
var col = new Object;
|
||
|
var childElt = new Object;
|
||
|
|
||
|
var tree = GetThreadTree();
|
||
|
// figure out what cell the click was in
|
||
|
tree.treeBoxObject.getCellAt(event.clientX, event.clientY, row, col, childElt);
|
||
|
if (row.value == -1)
|
||
|
return;
|
||
|
|
||
|
// if the cell is in a "cycler" column
|
||
|
// or if the user double clicked on the twisty,
|
||
|
// don't open the message in a new window
|
||
|
if (event.detail == 2 && !col.value.cycler && (childElt.value != "twisty")) {
|
||
|
ThreadPaneDoubleClick();
|
||
|
// double clicking should not toggle the open / close state of the
|
||
|
// thread. this will happen if we don't prevent the event from
|
||
|
// bubbling to the default handler in tree.xml
|
||
|
event.stopPropagation();
|
||
|
}
|
||
|
else if (col.value.id == "junkStatusCol") {
|
||
|
MsgJunkMailInfo(true);
|
||
|
}
|
||
|
else if (col.value.id == "threadCol" && !event.shiftKey &&
|
||
|
(event.ctrlKey || event.metaKey)) {
|
||
|
gDBView.ExpandAndSelectThreadByIndex(row.value, true);
|
||
|
event.stopPropagation();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function nsMsgDBViewCommandUpdater()
|
||
|
{}
|
||
|
|
||
|
nsMsgDBViewCommandUpdater.prototype =
|
||
|
{
|
||
|
updateCommandStatus : function()
|
||
|
{
|
||
|
// the back end is smart and is only telling us to update command status
|
||
|
// when the # of items in the selection has actually changed.
|
||
|
UpdateMailToolbar("dbview driven, thread pane");
|
||
|
},
|
||
|
|
||
|
displayMessageChanged : function(aFolder, aSubject, aKeywords)
|
||
|
{
|
||
|
if (!gDBView.suppressMsgDisplay)
|
||
|
setTitleFromFolder(aFolder, aSubject);
|
||
|
ClearPendingReadTimer(); // we are loading / selecting a new message so kill the mark as read timer for the currently viewed message
|
||
|
gHaveLoadedMessage = true;
|
||
|
goUpdateCommand("button_junk");
|
||
|
},
|
||
|
|
||
|
updateNextMessageAfterDelete : function()
|
||
|
{
|
||
|
SetNextMessageAfterDelete();
|
||
|
},
|
||
|
|
||
|
QueryInterface : function(iid)
|
||
|
{
|
||
|
if (iid.equals(Components.interfaces.nsIMsgDBViewCommandUpdater) ||
|
||
|
iid.equals(Components.interfaces.nsISupports))
|
||
|
return this;
|
||
|
|
||
|
throw Components.results.NS_NOINTERFACE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function HandleColumnClick(columnID)
|
||
|
{
|
||
|
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();
|
||
|
var simpleColumns = false;
|
||
|
try {
|
||
|
simpleColumns = !pref.getBoolPref("mailnews.thread_pane_column_unthreads");
|
||
|
}
|
||
|
catch (ex) {
|
||
|
}
|
||
|
if (sortType == nsMsgViewSortType.byThread) {
|
||
|
if (!dbview.supportsThreading)
|
||
|
return;
|
||
|
|
||
|
if (simpleColumns)
|
||
|
MsgToggleThreaded();
|
||
|
else if (dbview.viewFlags & nsMsgViewFlagsType.kThreadedDisplay)
|
||
|
MsgReverseSortThreadPane();
|
||
|
else
|
||
|
MsgSortByThread();
|
||
|
}
|
||
|
else {
|
||
|
if (!simpleColumns && (dbview.viewFlags & nsMsgViewFlagsType.kThreadedDisplay)) {
|
||
|
dbview.viewFlags &= ~nsMsgViewFlagsType.kThreadedDisplay;
|
||
|
MsgSortThreadPane(sortType);
|
||
|
}
|
||
|
else if (dbview.sortType == sortType) {
|
||
|
MsgReverseSortThreadPane();
|
||
|
}
|
||
|
else {
|
||
|
MsgSortThreadPane(sortType);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function MsgComposeDraftMessage()
|
||
|
{
|
||
|
var loadedFolder = GetLoadedMsgFolder();
|
||
|
var messageArray = GetSelectedMessages();
|
||
|
|
||
|
ComposeMessage(msgComposeType.Draft, msgComposeFormat.Default, loadedFolder, messageArray);
|
||
|
}
|
||
|
|
||
|
function ThreadPaneDoubleClick()
|
||
|
{
|
||
|
if (IsSpecialFolderSelected(MSG_FOLDER_FLAG_DRAFTS, true)) {
|
||
|
MsgComposeDraftMessage();
|
||
|
}
|
||
|
else if(IsSpecialFolderSelected(MSG_FOLDER_FLAG_TEMPLATES, true)) {
|
||
|
var loadedFolder = GetLoadedMsgFolder();
|
||
|
var messageArray = GetSelectedMessages();
|
||
|
ComposeMessage(msgComposeType.Template, msgComposeFormat.Default, loadedFolder, messageArray);
|
||
|
}
|
||
|
else {
|
||
|
MsgOpenSelectedMessages();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function ThreadPaneKeyPress(event)
|
||
|
{
|
||
|
if (event.keyCode == 13)
|
||
|
ThreadPaneDoubleClick();
|
||
|
}
|
||
|
|
||
|
function MsgSortByDate()
|
||
|
{
|
||
|
MsgSortThreadPane(nsMsgViewSortType.byDate);
|
||
|
}
|
||
|
|
||
|
function MsgSortBySender()
|
||
|
{
|
||
|
MsgSortThreadPane(nsMsgViewSortType.byAuthor);
|
||
|
}
|
||
|
|
||
|
function MsgSortByRecipient()
|
||
|
{
|
||
|
MsgSortThreadPane(nsMsgViewSortType.byRecipient);
|
||
|
}
|
||
|
|
||
|
function MsgSortByStatus()
|
||
|
{
|
||
|
MsgSortThreadPane(nsMsgViewSortType.byStatus);
|
||
|
}
|
||
|
|
||
|
function MsgSortByTags()
|
||
|
{
|
||
|
MsgSortThreadPane(nsMsgViewSortType.byTags);
|
||
|
}
|
||
|
|
||
|
function MsgSortByJunkStatus()
|
||
|
{
|
||
|
MsgSortThreadPane(nsMsgViewSortType.byJunkStatus);
|
||
|
}
|
||
|
|
||
|
function MsgSortByAttachments()
|
||
|
{
|
||
|
MsgSortThreadPane(nsMsgViewSortType.byAttachments);
|
||
|
}
|
||
|
|
||
|
function MsgSortBySubject()
|
||
|
{
|
||
|
MsgSortThreadPane(nsMsgViewSortType.bySubject);
|
||
|
}
|
||
|
|
||
|
function MsgSortByLocation()
|
||
|
{
|
||
|
MsgSortThreadPane(nsMsgViewSortType.byLocation);
|
||
|
}
|
||
|
|
||
|
function msgSortByAccount()
|
||
|
{
|
||
|
MsgSortThreadPane(nsMsgViewSortType.byAccount);
|
||
|
}
|
||
|
|
||
|
function MsgSortByFlagged()
|
||
|
{
|
||
|
MsgSortThreadPane(nsMsgViewSortType.byFlagged);
|
||
|
}
|
||
|
|
||
|
function MsgSortByPriority()
|
||
|
{
|
||
|
MsgSortThreadPane(nsMsgViewSortType.byPriority);
|
||
|
}
|
||
|
|
||
|
function MsgSortBySize()
|
||
|
{
|
||
|
MsgSortThreadPane(nsMsgViewSortType.bySize);
|
||
|
}
|
||
|
|
||
|
function MsgSortByUnread()
|
||
|
{
|
||
|
MsgSortThreadPane(nsMsgViewSortType.byUnread);
|
||
|
}
|
||
|
|
||
|
function MsgSortByOrderReceived()
|
||
|
{
|
||
|
MsgSortThreadPane(nsMsgViewSortType.byId);
|
||
|
}
|
||
|
|
||
|
function MsgSortByTotal()
|
||
|
{
|
||
|
dump("XXX fix MsgSortByTotal\n");
|
||
|
//MsgSortThreadPane(nsMsgViewSortType.byTotal);
|
||
|
}
|
||
|
|
||
|
function MsgSortByThread()
|
||
|
{
|
||
|
var dbview = GetDBView();
|
||
|
if(dbview && !dbview.supportsThreading)
|
||
|
return;
|
||
|
dbview.viewFlags |= nsMsgViewFlagsType.kThreadedDisplay;
|
||
|
dbview.viewFlags &= ~nsMsgViewFlagsType.kGroupBySort;
|
||
|
MsgSortThreadPane(nsMsgViewSortType.byId);
|
||
|
}
|
||
|
|
||
|
function MsgSortThreadPane(sortType)
|
||
|
{
|
||
|
var dbview = GetDBView();
|
||
|
|
||
|
if (dbview.viewFlags & nsMsgViewFlagsType.kGroupBySort)
|
||
|
{
|
||
|
dbview.viewFlags &= ~nsMsgViewFlagsType.kGroupBySort;
|
||
|
dbview.sortType = sortType; // save sort in current view
|
||
|
viewDebug("switching view to all msgs\n");
|
||
|
SwitchView("cmd_viewAllMsgs");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
dbview.sort(sortType, nsMsgViewSortOrder.ascending);
|
||
|
UpdateSortIndicators(sortType, nsMsgViewSortOrder.ascending);
|
||
|
}
|
||
|
|
||
|
function MsgReverseSortThreadPane()
|
||
|
{
|
||
|
var dbview = GetDBView();
|
||
|
if (dbview.sortOrder == nsMsgViewSortOrder.ascending) {
|
||
|
MsgSortDescending();
|
||
|
}
|
||
|
else {
|
||
|
MsgSortAscending();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function MsgToggleThreaded()
|
||
|
{
|
||
|
var dbview = GetDBView();
|
||
|
|
||
|
dbview.viewFlags ^= nsMsgViewFlagsType.kThreadedDisplay;
|
||
|
if (dbview.viewFlags & nsMsgViewFlagsType.kGroupBySort)
|
||
|
{
|
||
|
dbview.viewFlags &= ~nsMsgViewFlagsType.kGroupBySort;
|
||
|
viewDebug("switching view to all msgs\n");
|
||
|
SwitchView("cmd_viewAllMsgs");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
dbview.sort(dbview.sortType, dbview.sortOrder);
|
||
|
UpdateSortIndicators(dbview.sortType, dbview.sortOrder);
|
||
|
}
|
||
|
|
||
|
function MsgSortThreaded()
|
||
|
{
|
||
|
var dbview = GetDBView();
|
||
|
var viewFlags = dbview.viewFlags;
|
||
|
|
||
|
if (viewFlags & nsMsgViewFlagsType.kGroupBySort)
|
||
|
{
|
||
|
dbview.viewFlags &= ~nsMsgViewFlagsType.kGroupBySort;
|
||
|
viewDebug("switching view to all msgs\n");
|
||
|
SwitchView("cmd_viewAllMsgs");
|
||
|
}
|
||
|
// Toggle if not already threaded.
|
||
|
else if ((viewFlags & nsMsgViewFlagsType.kThreadedDisplay) == 0)
|
||
|
MsgToggleThreaded();
|
||
|
}
|
||
|
|
||
|
function MsgGroupBySort()
|
||
|
{
|
||
|
var dbview = GetDBView();
|
||
|
var viewFlags = dbview.viewFlags;
|
||
|
var sortOrder = dbview.sortOrder;
|
||
|
var sortType = dbview.sortType;
|
||
|
var count = new Object;
|
||
|
var msgFolder = dbview.msgFolder;
|
||
|
|
||
|
var sortTypeSupportsGrouping = (sortType == nsMsgViewSortType.byAuthor
|
||
|
|| sortType == nsMsgViewSortType.byDate || sortType == nsMsgViewSortType.byPriority
|
||
|
|| sortType == nsMsgViewSortType.bySubject || sortType == nsMsgViewSortType.byTags
|
||
|
|| sortType == nsMsgViewSortType.byStatus || sortType == nsMsgViewSortType.byRecipient
|
||
|
|| sortType == nsMsgViewSortType.byAccount || sortType == nsMsgViewSortType.byFlagged
|
||
|
|| sortType == nsMsgViewSortType.byAttachments);
|
||
|
|
||
|
if (!dbview.supportsThreading || !sortTypeSupportsGrouping)
|
||
|
return; // we shouldn't be trying to group something we don't support grouping for...
|
||
|
|
||
|
viewFlags |= nsMsgViewFlagsType.kThreadedDisplay | nsMsgViewFlagsType.kGroupBySort;
|
||
|
// null this out, so we don't try sort.
|
||
|
if (gDBView) {
|
||
|
gDBView.close();
|
||
|
gDBView = null;
|
||
|
}
|
||
|
var dbviewContractId = "@mozilla.org/messenger/msgdbview;1?type=group";
|
||
|
gDBView = Components.classes[dbviewContractId].createInstance(Components.interfaces.nsIMsgDBView);
|
||
|
|
||
|
if (!gThreadPaneCommandUpdater)
|
||
|
gThreadPaneCommandUpdater = new nsMsgDBViewCommandUpdater();
|
||
|
|
||
|
|
||
|
gDBView.init(messenger, msgWindow, gThreadPaneCommandUpdater);
|
||
|
gDBView.open(msgFolder, sortType, sortOrder, viewFlags, count);
|
||
|
RerootThreadPane();
|
||
|
UpdateSortIndicators(sortType, nsMsgViewSortOrder.ascending);
|
||
|
}
|
||
|
|
||
|
function MsgSortUnthreaded()
|
||
|
{
|
||
|
// Toggle if not already unthreaded.
|
||
|
if ((GetDBView().viewFlags & nsMsgViewFlagsType.kThreadedDisplay) != 0)
|
||
|
MsgToggleThreaded();
|
||
|
}
|
||
|
|
||
|
function MsgSortAscending()
|
||
|
{
|
||
|
var dbview = GetDBView();
|
||
|
dbview.sort(dbview.sortType, nsMsgViewSortOrder.ascending);
|
||
|
UpdateSortIndicators(dbview.sortType, nsMsgViewSortOrder.ascending);
|
||
|
}
|
||
|
|
||
|
function MsgSortDescending()
|
||
|
{
|
||
|
var dbview = GetDBView();
|
||
|
dbview.sort(dbview.sortType, nsMsgViewSortOrder.descending);
|
||
|
UpdateSortIndicators(dbview.sortType, nsMsgViewSortOrder.descending);
|
||
|
}
|
||
|
|
||
|
function groupedBySortUsingDummyRow()
|
||
|
{
|
||
|
return (gDBView.viewFlags & nsMsgViewFlagsType.kGroupBySort) &&
|
||
|
(gDBView.sortType != nsMsgViewSortType.bySubject);
|
||
|
}
|
||
|
|
||
|
function UpdateSortIndicators(sortType, sortOrder)
|
||
|
{
|
||
|
// Remove the sort indicator from all the columns
|
||
|
var treeColumns = document.getElementById('threadCols').childNodes;
|
||
|
for (var i = 0; i < treeColumns.length; i++)
|
||
|
treeColumns[i].removeAttribute('sortDirection');
|
||
|
|
||
|
// show the twisties if the view is threaded
|
||
|
var threadCol = document.getElementById("threadCol");
|
||
|
var sortedColumn;
|
||
|
// set the sort indicator on the column we are sorted by
|
||
|
var colID = ConvertSortTypeToColumnID(sortType);
|
||
|
if (colID)
|
||
|
sortedColumn = document.getElementById(colID);
|
||
|
|
||
|
var dbview = GetDBView();
|
||
|
var currCol = dbview.viewFlags & nsMsgViewFlagsType.kGroupBySort
|
||
|
? sortedColumn : document.getElementById("subjectCol");
|
||
|
|
||
|
if (dbview.viewFlags & nsMsgViewFlagsType.kGroupBySort)
|
||
|
{
|
||
|
var threadTree = document.getElementById("threadTree");
|
||
|
var subjectCol = document.getElementById("subjectCol");
|
||
|
|
||
|
if (groupedBySortUsingDummyRow())
|
||
|
{
|
||
|
currCol.removeAttribute("primary");
|
||
|
subjectCol.setAttribute("primary", "true");
|
||
|
}
|
||
|
|
||
|
// hide the threaded column when in grouped view since you can't do
|
||
|
// threads inside of a group.
|
||
|
document.getElementById("threadCol").collapsed = true;
|
||
|
}
|
||
|
|
||
|
// clear primary attribute from group column if going to a non-grouped view.
|
||
|
if (!(dbview.viewFlags & nsMsgViewFlagsType.kGroupBySort))
|
||
|
document.getElementById("threadCol").collapsed = false;
|
||
|
|
||
|
if ((dbview.viewFlags & nsMsgViewFlagsType.kThreadedDisplay) && !groupedBySortUsingDummyRow()) {
|
||
|
threadCol.setAttribute("sortDirection", "ascending");
|
||
|
currCol.setAttribute("primary", "true");
|
||
|
}
|
||
|
else {
|
||
|
threadCol.removeAttribute("sortDirection");
|
||
|
currCol.removeAttribute("primary");
|
||
|
}
|
||
|
|
||
|
if (sortedColumn) {
|
||
|
if (sortOrder == nsMsgViewSortOrder.ascending) {
|
||
|
sortedColumn.setAttribute("sortDirection","ascending");
|
||
|
}
|
||
|
else {
|
||
|
sortedColumn.setAttribute("sortDirection","descending");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function IsSpecialFolderSelected(flags, checkAncestors)
|
||
|
{
|
||
|
var selectedFolder = GetThreadPaneFolder();
|
||
|
return IsSpecialFolder(selectedFolder, flags, checkAncestors);
|
||
|
}
|
||
|
|
||
|
function GetThreadTree()
|
||
|
{
|
||
|
if (gThreadTree) return gThreadTree;
|
||
|
gThreadTree = document.getElementById('threadTree');
|
||
|
return gThreadTree;
|
||
|
}
|
||
|
|
||
|
function GetThreadPaneFolder()
|
||
|
{
|
||
|
try {
|
||
|
return gDBView.msgFolder;
|
||
|
}
|
||
|
catch (ex) {
|
||
|
return null;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function EnsureRowInThreadTreeIsVisible(index)
|
||
|
{
|
||
|
if (index < 0)
|
||
|
return;
|
||
|
|
||
|
var tree = GetThreadTree();
|
||
|
tree.treeBoxObject.ensureRowIsVisible(index);
|
||
|
}
|
||
|
|
||
|
function RerootThreadPane()
|
||
|
{
|
||
|
SetNewsFolderColumns();
|
||
|
|
||
|
var treeView = gDBView.QueryInterface(Components.interfaces.nsITreeView);
|
||
|
if (treeView)
|
||
|
{
|
||
|
var tree = GetThreadTree();
|
||
|
tree.boxObject.QueryInterface(Components.interfaces.nsITreeBoxObject).view = treeView;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
function ThreadPaneOnLoad()
|
||
|
{
|
||
|
var tree = GetThreadTree();
|
||
|
|
||
|
tree.addEventListener("click",ThreadPaneOnClick,true);
|
||
|
|
||
|
// The mousedown event listener below should only be added in the thread
|
||
|
// pane of the mailnews 3pane window, not in the advanced search window.
|
||
|
if(tree.parentNode.id == "searchResultListBox")
|
||
|
return;
|
||
|
|
||
|
tree.addEventListener("mousedown",TreeOnMouseDown,true);
|
||
|
}
|
||
|
|
||
|
function ThreadPaneSelectionChanged()
|
||
|
{
|
||
|
UpdateStatusMessageCounts(gMsgFolderSelected);
|
||
|
if (!gRightMouseButtonDown)
|
||
|
GetThreadTree().view.selectionChanged();
|
||
|
}
|
||
|
|
||
|
addEventListener("load",ThreadPaneOnLoad,true);
|