gecko-dev/mailnews/base/resources/content/commandglue.js

743 lines
18 KiB
JavaScript

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* The contents of this file are subject to the Netscape 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/NPL/
*
* 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 Netscape are
* Copyright (C) 1998-1999 Netscape Communications Corporation. All
* Rights Reserved.
*/
/*
* Command-specific code. This stuff should be called by the widgets
*/
var gBeforeFolderLoadTime;
function OpenURL(url)
{
dump("\n\nOpenURL from XUL\n\n\n");
messenger.SetWindow(window, msgWindow);
messenger.OpenURL(url);
}
function FindIncomingServer(uri)
{
//dump("FindIncomingServer("+uri+")\n");
var server=null;
if (!uri) return server;
try {
var resource = RDF.GetResource(uri);
var msgfolder = resource.QueryInterface(Components.interfaces.nsIMsgFolder);
server = msgfolder.server;
//dump("server = " + server + "\n");
return server;
}
catch (ex) {
return null;
}
}
function getIdentityForSelectedServer()
{
var folderTree = GetFolderTree();
var identity = null;
var selectedFolderList = folderTree.selectedItems;
if(selectedFolderList.length > 0) {
var selectedFolder = selectedFolderList[0];
var folderUri = selectedFolder.getAttribute('id');
// dump("selectedFolder uri = " + uri + "\n");
// get the incoming server associated with this folder uri
var server = FindIncomingServer(folderUri);
// dump("server = " + server + "\n");
// get the identity associated with this server
var identities = accountManager.GetIdentitiesForServer(server);
// dump("identities = " + identities + "\n");
// just get the first one
if (identities.Count() > 0 ) {
identity = identities.GetElementAt(0).QueryInterface(Components.interfaces.nsIMsgIdentity);
}
}
return identity;
}
function ComposeMessage(type, format) //type is a nsIMsgCompType and format is a nsIMsgCompFormat
{
var msgComposeType = Components.interfaces.nsIMsgCompType;
var identity = null;
var newsgroup = null;
try
{
var folderTree = GetFolderTree();
var selectedFolderList = folderTree.selectedItems;
if(selectedFolderList.length > 0)
{
var selectedFolder = selectedFolderList[0];
var uri = selectedFolder.getAttribute('id');
// dump("selectedFolder uri = " + uri + "\n");
// get the incoming server associated with this uri
var server = FindIncomingServer(uri);
// if they hit new and they are reading a newsgroup
// turn this into a new post, not a new mail message
if (type == msgComposeType.New) {
if (server.type == "nntp") {
type = msgComposeType.NewsPost;
// from the uri, get the newsgroup name
var resource = RDF.GetResource(uri);
var msgfolder = resource.QueryInterface(Components.interfaces.nsIMsgFolder);
if (msgfolder.isServer)
newsgroup = "";
else
newsgroup = msgfolder.name;
}
}
}
identity = getIdentityForSelectedServer();
// dump("identity = " + identity + "\n");
}
catch (ex)
{
// dump("failed to get an identity to pre-select: " + ex + "\n");
}
dump("\nComposeMessage from XUL: " + identity + "\n");
var uri = null;
if (! msgComposeService)
{
dump("### msgComposeService is invalid\n");
return;
}
if (type == msgComposeType.New) //new message
{
//dump("OpenComposeWindow with " + identity + "\n");
msgComposeService.OpenComposeWindow(null, null, type, format, identity);
return;
}
else if (type == msgComposeType.NewsPost)
{
dump("OpenComposeWindow with " + identity + " and " + newsgroup + "\n");
msgComposeService.OpenComposeWindow(null, newsgroup, type, format, identity);
return;
}
var tree = GetThreadTree();
if (tree)
{
var nodeList = tree.selectedItems;
var appCore = FindMessenger();
if (appCore)
appCore.SetWindow(window, msgWindow);
var object = null;
if (nodeList && nodeList.length > 0)
{
uri = "";
for (var i = 0; i < nodeList.length && i < 8; i ++)
{
dump('i = '+ i);
dump('\n');
if (type == msgComposeType.Reply || type == msgComposeType.ReplyAll || type == msgComposeType.ForwardInline ||
type == msgComposeType.Template || type == msgComposeType.Draft)
{
msgComposeService.OpenComposeWindow(null, nodeList[i].getAttribute('id'), type, format, identity);
}
else
{
if (i)
uri += ","
uri += nodeList[i].getAttribute('id');
}
}
if (type == msgComposeType.ForwardAsAttachment)
{
msgComposeService.OpenComposeWindow(null, uri, type, format, identity);
}
}
else
dump("### nodeList is invalid\n");
}
else
dump("### tree is invalid\n");
}
function GetNewMessages()
{
var folderTree = GetFolderTree();
var selectedFolderList = folderTree.selectedItems;
if(selectedFolderList.length > 0)
{
var selectedFolder = selectedFolderList[0];
messenger.GetNewMessages(folderTree.database, selectedFolder.resource);
}
else {
dump("Nothing was selected\n");
}
}
function LoadMessage(messageNode)
{
var uri = messageNode.getAttribute('id');
dump(uri);
if(uri != gCurrentDisplayedMessage)
{
gCurrentDisplayedMessage = uri;
OpenURL(uri);
}
}
function ChangeFolderByDOMNode(folderNode)
{
var uri = folderNode.getAttribute('id');
dump(uri + "\n");
var isThreaded = folderNode.getAttribute('threaded');
if (uri)
ChangeFolderByURI(uri, isThreaded == "true", "");
}
function ChangeFolderByURI(uri, isThreaded, sortID)
{
dump('In ChangeFolderByURI\n');
var resource = RDF.GetResource(uri);
var msgfolder =
resource.QueryInterface(Components.interfaces.nsIMsgFolder);
if (msgfolder.isServer)
window.title = msgfolder.name;
else if (msgfolder.server)
window.title = msgfolder.name + " on " +
msgfolder.server.prettyName;
else
window.title = msgfolder.name;
gBeforeFolderLoadTime = new Date();
gCurrentLoadingFolderURI = uri;
if(msgfolder.manyHeadersToDownload())
{
try
{
gCurrentFolderToReroot = uri;
gCurrentLoadingFolderIsThreaded = isThreaded;
gCurrentLoadingFolderSortID = sortID;
msgfolder.startFolderLoading();
msgfolder.updateFolder(msgWindow);
}
catch(ex)
{
dump("Error loading with many headers to download\n");
}
}
else
{
gCurrentFolderToReroot = "";
gCurrentLoadingFolderIsThreaded = false;
gCurrentLoadingFolderSortID = "";
RerootFolder(uri, msgfolder, isThreaded, sortID);
//Need to do this after rerooting folder. Otherwise possibility of receiving folder loaded
//notification before folder has actually changed.
msgfolder.updateFolder(msgWindow);
}
}
function RerootFolder(uri, newFolder, isThreaded, sortID)
{
dump('In reroot folder\n');
var folder = GetThreadTreeFolder();
ClearThreadTreeSelection();
//Set the window's new open folder.
msgWindow.openFolder = newFolder;
//Set threaded state
ShowThreads(isThreaded);
folder.setAttribute('ref', uri);
UpdateStatusMessageCounts(newFolder);
}
function UpdateStatusMessageCounts(folder)
{
var unreadElement = GetUnreadCountElement();
var totalElement = GetTotalCountElement();
if(folder && unreadElement && totalElement)
{
var numUnread = folder.getNumUnread(false);
var numTotal = folder.getTotalMessages(false);
unreadElement.setAttribute("value", numUnread);
totalElement.setAttribute("value", numTotal);
}
}
function SaveThreadPaneSelection()
{
var tree = GetThreadTree();
var selectedItems = tree.selectedItems;
var numSelected = selectedItems.length;
var selectionArray = new Array(numSelected);
for(var i = 0; i < numSelected; i++)
{
selectionArray[i] = selectedItems[i].getAttribute("id");
}
return selectionArray;
}
function RestoreThreadPaneSelection(selectionArray)
{
var tree = GetThreadTree();
var numSelected = selectionArray.length;
msgNavigationService.EnsureDocumentIsLoaded(document);
var messageElement;
for(var i = 0 ; i < numSelected; i++)
{
messageElement = document.getElementById(selectionArray[i]);
if(!messageElement && messageView.showThreads)
{
var treeFolder = GetThreadTreeFolder();
var folderURI = treeFolder.getAttribute('ref');
var folderResource = RDF.GetResource(folderURI);
var folder = folderResource.QueryInterface(Components.interfaces.nsIMsgFolder);
var messageResource = RDF.GetResource(selectionArray[i]);
var message = messageResource.QueryInterface(Components.interfaces.nsIMessage);
var topLevelMessage = GetTopLevelMessageForMessage(message, folder);
var topLevelResource = topLevelMessage.QueryInterface(Components.interfaces.nsIRDFResource);
var topLevelURI = topLevelResource.Value;
var topElement = document.getElementById(topLevelURI);
if(topElement)
{
msgNavigationService.OpenTreeitemAndDescendants(topElement);
}
messageElement = document.getElementById(selectionArray[i]);
}
tree.addItemToSelection(messageElement);
if(messageElement && (i==0))
tree.ensureElementIsVisible(messageElement);
}
}
function SortThreadPane(column, sortKey, secondarySortKey)
{
var node = document.getElementById(column);
if(!node)
return false;
var selection = SaveThreadPaneSelection();
var beforeSortTime = new Date();
var result = SortColumn(node, sortKey, secondarySortKey);
var afterSortTime = new Date();
var timeToSort = (afterSortTime.getTime() - beforeSortTime.getTime())/1000;
if(showPerformance)
dump("timeToSort is " + timeToSort + "seconds\n");
RestoreThreadPaneSelection(selection);
return result;
}
function SortFolderPane(column, sortKey)
{
var node = FindInSidebar(window, column);
if(!node)
{
dump('Couldnt find sort column\n');
return false;
}
return SortColumn(node, sortKey, null);
}
function SortColumn(node, sortKey, secondarySortKey)
{
dump('In sortColumn\n');
var xulSortService = Components.classes["component://netscape/rdf/xul-sort-service"].getService();
if (xulSortService)
{
xulSortService = xulSortService.QueryInterface(Components.interfaces.nsIXULSortService);
if (xulSortService)
{
// sort!!!
sortDirection = "ascending";
var currentDirection = node.getAttribute('sortDirection');
if (currentDirection == "ascending")
sortDirection = "descending";
else if (currentDirection == "descending")
sortDirection = "ascending";
else sortDirection = "ascending";
try
{
if(secondarySortKey)
node.setAttribute('rdf:resource2', secondarySortKey);
xulSortService.Sort(node, sortKey, sortDirection);
}
catch(e)
{
//dump("Sort failed: " + e + "\n");
}
}
}
}
function GetSelectedFolderResource()
{
var folderTree = GetFolderTree();
var selectedFolderList = folderTree.selectedItems;
var selectedFolder = selectedFolderList[0];
var uri = selectedFolder.getAttribute('id');
var folderResource = RDF.GetResource(uri);
return folderResource;
}
function SetFolderCharset(folderResource, aCharset)
{
var folderTree = GetFolderTree();
var db = folderTree.database;
var db2 = db.QueryInterface(Components.interfaces.nsIRDFDataSource);
var charsetResource = RDF.GetLiteral(aCharset);
var charsetProperty = RDF.GetResource("http://home.netscape.com/NC-rdf#Charset");
db2.Assert(folderResource, charsetProperty, charsetResource, true);
}
function ToggleMessageRead(treeItem)
{
var tree = GetThreadTree();
var isUnread = treeItem.getAttribute('IsUnread');
var unread = (isUnread == "true");
messenger.MarkMessageRead(tree.database, treeItem.resource, unread);
}
function ToggleMessageFlagged(treeItem)
{
var tree = GetThreadTree();
var flaggedValue = treeItem.getAttribute('Flagged');
dump('flaggedValue is ' + flaggedValue);
dump('\n');
var flagged = (flaggedValue =="flagged");
messenger.MarkMessageFlagged(tree.database, treeItem.resource, !flagged);
}
//Called when the splitter in between the thread and message panes is clicked.
function OnClickThreadAndMessagePaneSplitter()
{
var collapsed = IsThreadAndMessagePaneSplitterCollapsed();
//collapsed is the previous state so we know we are opening.
if(collapsed)
LoadSelectionIntoMessagePane();
}
//Called when selection changes in the thread pane.
function ThreadPaneSelectionChange()
{
var collapsed = IsThreadAndMessagePaneSplitterCollapsed();
if(!collapsed)
{
LoadSelectionIntoMessagePane();
}
}
//takes the selection from the thread pane and loads it into the message pane
function LoadSelectionIntoMessagePane()
{
var tree = GetThreadTree();
var selArray = tree.selectedItems;
if ( selArray && (selArray.length == 1) )
LoadMessage(selArray[0]);
else
{
// don't necessarily clear the message pane...if you uncomment this,
// you'll be introducing a large inefficiency when deleting messages...as deleting
// a msg brings us here twice...so we end up clearing the message pane twice for no
// good reason...
// ClearMessagePane();
}
}
function FolderPaneSelectionChange()
{
var tree = GetFolderTree();
if(tree)
{
var selArray = tree.selectedItems;
if ( selArray && (selArray.length == 1) )
{
ChangeFolderByDOMNode(selArray[0]);
// explicitly force the message pane to get cleared when we switch folders
ClearMessagePane();
}
else
{
var threadTree = GetThreadTree();
ClearThreadTreeSelection();
threadTree.setAttribute('ref', null);
ClearMessagePane();
}
}
}
function OpenFolderTreeToFolder(folderURI)
{
var tree = GetFolderTree();
return OpenToFolder(tree, folderURI);
}
function OpenToFolder(item, folderURI)
{
if(item.nodeType != Node.ELEMENT_NODE)
return null;
var uri = item.getAttribute('id');
dump(uri);
dump('\n');
if(uri == folderURI)
{
dump('found folder: ' + uri);
dump('\n');
return item;
}
var children = item.childNodes;
var length = children.length;
var i;
dump('folder ' + uri);
dump('has ' + length);
dump('children\n');
for(i = 0; i < length; i++)
{
var child = children[i];
var folder = OpenToFolder(child, folderURI);
if(folder)
{
child.setAttribute('open', 'true');
return folder;
}
}
return null;
}
function IsSpecialFolderSelected(folderName)
{
var selectedFolder = GetThreadTreeFolder();
var id = selectedFolder.getAttribute('ref');
var folderResource = RDF.GetResource(id);
if(!folderResource)
return false;
var folderTree = GetFolderTree();
var db = folderTree.database;
if (!db) return false;
db = db.QueryInterface(Components.interfaces.nsIRDFDataSource);
if (!db) return false;
var property =
RDF.GetResource('http://home.netscape.com/NC-rdf#SpecialFolder');
if (!property) return false;
var result = db.GetTarget(folderResource, property , true);
if (!result) return false;
result = result.QueryInterface(Components.interfaces.nsIRDFLiteral);
if (!result) return false;
if(result.Value == folderName)
return true;
return false;
}
function ChangeThreadView()
{
var folder = GetSelectedFolder();
var threadColumn = document.getElementById('ThreadColumnHeader');
if(threadColumn)
{
var currentView = threadColumn.getAttribute('currentView');
if(currentView== 'threaded')
{
ShowThreads(false);
if(folder)
folder.setAttribute('threaded', "");
}
else if(currentView == 'unthreaded')
{
ShowThreads(true);
if(folder)
folder.setAttribute('threaded', "true");
}
RefreshThreadTreeView();
}
}
function ShowThreads(showThreads)
{
dump('in showthreads\n');
if(messageView)
{
messageView.showThreads = showThreads;
var threadColumn = document.getElementById('ThreadColumnHeader');
if(threadColumn)
{
if(showThreads)
{
threadColumn.setAttribute('currentView', 'threaded');
}
else
{
threadColumn.setAttribute('currentView', 'unthreaded');
}
}
}
}
function GetNextMessageAfterDelete(messages)
{
var count = messages.length;
var curMessage = messages[0];
var nextMessage = null;
var tree = GetThreadTree();
//search forward
while(curMessage)
{
nextMessage = msgNavigationService.FindNextMessage(navigateAny, tree, curMessage, RDF, document, false, messageView.showThreads);
if(nextMessage)
{
if(nextMessage.getAttribute("selected") != "true")
{
break;
}
}
curMessage = nextMessage;
}
//if no nextmessage then search backwards
if(!nextMessage)
{
var curMessage = messages[0];
var nextMessage = null;
//search forward
while(curMessage)
{
nextMessage = msgNavigationService.FindPreviousMessage(navigateAny, tree, curMessage, RDF, document, false, messageView.showThreads);
if(nextMessage)
{
if(nextMessage.getAttribute("selected") != "true")
{
break;
}
}
curMessage = nextMessage;
}
}
return nextMessage;
}
function SelectNextMessage(nextMessage)
{
var tree = GetThreadTree();
ChangeSelection(tree, nextMessage);
}
function GetSelectTrashUri(folder)
{
if (!folder) return null;
var uri = folder.getAttribute('id');
dump (uri + "\n");
var resource = RDF.GetResource(uri);
var msgFolder =
resource.QueryInterface(Components.interfaces.nsIMsgFolder);
if (msgFolder)
{
dump("GetSelectTrashUri" + "\n");
var rootFolder = msgFolder.rootFolder;
var numFolder;
var out = new Object();
var trashFolder = rootFolder.getFoldersWithFlag(0x0100, 1, out);
numFolder = out.value;
dump (numFolder + "\n");
if (trashFolder)
{
dump (trashFolder.URI + "\n");
return trashFolder.URI;
}
}
return null;
}
function Undo()
{
messenger.Undo(msgWindow);
}
function Redo()
{
messenger.Redo(msgWindow);
}