gecko-dev/mail/base/content/messageWindow.js

891 строка
23 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.
*/
/* This is where functions related to the standalone message window are kept */
/* globals for a particular window */
var compositeDataSourceContractID = datasourceContractIDPrefix + "composite-datasource";
var gCompositeDataSource;
var gCurrentMessageUri;
var gCurrentFolderUri;
var gThreadPaneCommandUpdater = null;
var gCurrentMessageIsDeleted = false;
var gNextMessageViewIndexAfterDelete = -2;
// the folderListener object
var folderListener = {
OnItemAdded: function(parentItem, item, view) {},
OnItemRemoved: function(parentItem, item, view) {
var parentFolderResource = parentItem.QueryInterface(Components.interfaces.nsIRDFResource);
if(!parentFolderResource)
return;
var parentURI = parentFolderResource.Value;
if(parentURI != gCurrentFolderUri)
return;
var deletedMessageHdr = item.QueryInterface(Components.interfaces.nsIMsgDBHdr);
if (extractMsgKeyFromURI() == deletedMessageHdr.messageKey)
gCurrentMessageIsDeleted = true;
},
OnItemPropertyChanged: function(item, property, oldValue, newValue) {},
OnItemIntPropertyChanged: function(item, property, oldValue, newValue) { },
OnItemBoolPropertyChanged: function(item, property, oldValue, newValue) {},
OnItemUnicharPropertyChanged: function(item, property, oldValue, newValue){},
OnItemPropertyFlagChanged: function(item, property, oldFlag, newFlag) {},
OnItemEvent: function(folder, event) {
if (event.GetUnicode() == "DeleteOrMoveMsgCompleted") {
HandleDeleteOrMoveMsgCompleted(folder);
}
else if (event.GetUnicode() == "DeleteOrMoveMsgFailed") {
HandleDeleteOrMoveMsgFailed(folder);
}
else if (event.GetUnicode() == "msgLoaded") {
OnMsgLoaded(folder, gCurrentMessageUri);
}
}
}
var messagepaneObserver = {
canHandleMultipleItems: false,
onDrop: function (aEvent, aData, aDragSession)
{
var sourceUri = aData.data;
if (sourceUri != gCurrentMessageUri)
{
var msgHdr = GetMsgHdrFromUri(sourceUri);
var folderUri = msgHdr.folder.URI;
if (folderUri != gCurrentFolderUri)
UpdateDBView(folderUri);
SelectMessage(sourceUri);
}
},
onDragOver: function (aEvent, aFlavour, aDragSession)
{
var messagepanebox = document.getElementById("messagepanebox");
messagepanebox.setAttribute("dragover", "true");
},
onDragExit: function (aEvent, aDragSession)
{
var messagepanebox = document.getElementById("messagepanebox");
messagepanebox.removeAttribute("dragover");
},
canDrop: function(aEvent, aDragSession) //allow drop from mail:3pane window only - 4xp
{
var doc = aDragSession.sourceNode.ownerDocument;
var elem = doc.getElementById("messengerWindow");
return (elem && (elem.getAttribute("windowtype") == "mail:3pane"));
},
getSupportedFlavours: function ()
{
var flavourSet = new FlavourSet();
flavourSet.appendFlavour("text/x-moz-message");
return flavourSet;
}
};
function UpdateDBView(folderUri)
{
var dbview = GetDBView(); //close old folder view
if (dbview) {
dbview.close();
}
SelectFolder(folderUri);
CreateView(null); //create new folder view
}
function nsMsgDBViewCommandUpdater()
{}
function UpdateStandAloneMessageCounts()
{
// hook for extra toolbar items
var observerService = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);
observerService.notifyObservers(window, "mail:updateStandAloneMessageCounts", "");
}
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, std alone window");
},
displayMessageChanged : function(aFolder, aSubject, aKeywords)
{
setTitleFromFolder(aFolder, aSubject);
gCurrentMessageUri = gDBView.URIForFirstSelectedMessage;
UpdateStandAloneMessageCounts();
SetKeywords(aKeywords);
},
QueryInterface : function(iid)
{
if(iid.equals(Components.interfaces.nsIMsgDBViewCommandUpdater))
return this;
throw Components.results.NS_NOINTERFACE;
return null;
}
}
// from MailNewsTypes.h
const nsMsgKey_None = 0xFFFFFFFF;
function HandleDeleteOrMoveMsgCompleted(folder)
{
dump("In HandleDeleteOrMoveMsgCompleted\n");
var folderResource = folder.QueryInterface(Components.interfaces.nsIRDFResource);
if(!folderResource)
return;
var folderUri = folderResource.Value;
if((folderUri == gCurrentFolderUri) && gCurrentMessageIsDeleted)
{
gCurrentMessageIsDeleted = false;
if (gNextMessageViewIndexAfterDelete != nsMsgKey_None)
{
var nextMstKey = gDBView.getKeyAt(gNextMessageViewIndexAfterDelete);
if (nextMstKey != nsMsgKey_None) {
gDBView.loadMessageByMsgKey(nextMstKey);
}
else {
window.close();
}
}
else
{
// close the stand alone window because there are no more messages in the folder
window.close();
}
}
}
function HandleDeleteOrMoveMsgFailed(folder)
{
var folderResource = folder.QueryInterface(Components.interfaces.nsIRDFResource);
if(!folderResource)
return;
var folderUri = folderResource.Value;
if((folderUri == gCurrentFolderUri) && gCurrentMessageIsDeleted)
{
gCurrentMessageIsDeleted = false;
}
}
function OnLoadMessageWindow()
{
HideMenus();
AddMailOfflineObserver();
CreateMailWindowGlobals();
CreateMessageWindowGlobals();
verifyAccounts(null);
InitMsgWindow();
messenger.SetWindow(window, msgWindow);
InitializeDataSources();
// FIX ME - later we will be able to use onload from the overlay
OnLoadMsgHeaderPane();
try {
var nsIFolderListener = Components.interfaces.nsIFolderListener;
var notifyFlags = nsIFolderListener.removed | nsIFolderListener.event;
mailSession.AddFolderListener(folderListener, notifyFlags);
} catch (ex) {
dump("Error adding to session: " +ex + "\n");
}
var originalView = null;
if(window.arguments)
{
if(window.arguments[0])
{
gCurrentMessageUri = window.arguments[0];
}
else
{
gCurrentMessageUri = null;
}
if(window.arguments[1])
{
gCurrentFolderUri = window.arguments[1];
}
else
{
gCurrentFolderUri = null;
}
if (window.arguments[2])
originalView = window.arguments[2];
}
CreateView(originalView)
setTimeout("var msgKey = extractMsgKeyFromURI(gCurrentMessageUri); gDBView.loadMessageByMsgKey(msgKey); gNextMessageViewIndexAfterDelete = gDBView.msgToSelectAfterDelete; UpdateStandAloneMessageCounts();", 0);
SetupCommandUpdateHandlers();
var messagePaneFrame = top.frames['messagepane'];
if(messagePaneFrame)
messagePaneFrame.focus();
}
function CreateView(originalView)
{
var msgFolder = GetLoadedMsgFolder();
// extract the sort type, the sort order,
var sortType;
var sortOrder;
var viewFlags;
var viewType;
if (originalView)
{
viewType = originalView.viewType;
viewFlags = originalView.viewFlags;
sortType = originalView.sortType;
sortOrder = originalView.sortOrder;
}
else if (msgFolder)
{
var msgDatabase = msgFolder.getMsgDatabase(msgWindow);
if (msgDatabase)
{
var dbFolderInfo = msgDatabase.dBFolderInfo;
sortType = dbFolderInfo.sortType;
sortOrder = dbFolderInfo.sortOrder;
viewFlags = dbFolderInfo.viewFlags;
viewType = dbFolderInfo.viewType;
msgDatabase = null;
dbFolderInfo = null;
}
}
// create a db view
CreateBareDBView(originalView, msgFolder, viewType, viewFlags, sortType, sortOrder);
var uri;
if (gCurrentMessageUri)
uri = gCurrentMessageUri;
else if (gCurrentFolderUri)
uri = gCurrentFolderUri;
else
uri = null;
SetUpToolbarButtons(uri);
// hook for extra toolbar items
var observerService = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);
observerService.notifyObservers(window, "mail:setupToolbarItems", uri);
}
function extractMsgKeyFromURI()
{
var msgKey = -1;
var msgService = messenger.messageServiceFromURI(gCurrentMessageUri);
if (msgService)
{
var msgHdr = msgService.messageURIToMsgHdr(gCurrentMessageUri);
if (msgHdr)
msgKey = msgHdr.messageKey;
}
return msgKey;
}
function HideMenus()
{
var message_menuitem=document.getElementById('menu_showMessage');
if(message_menuitem)
message_menuitem.setAttribute("hidden", "true");
var expandOrCollapseMenu = document.getElementById('menu_expandOrCollapse');
if(expandOrCollapseMenu)
expandOrCollapseMenu.setAttribute("hidden", "true");
var renameFolderMenu = document.getElementById('menu_renameFolder');
if(renameFolderMenu)
renameFolderMenu.setAttribute("hidden", "true");
var viewMessagesMenu = document.getElementById('viewMessagesMenu');
if(viewMessagesMenu)
viewMessagesMenu.setAttribute("hidden", "true");
var openMessageMenu = document.getElementById('openMessageWindowMenuitem');
if(openMessageMenu)
openMessageMenu.setAttribute("hidden", "true");
var viewSortMenu = document.getElementById('viewSortMenu');
if(viewSortMenu)
viewSortMenu.setAttribute("hidden", "true");
var viewThreadedMenu = document.getElementById('menu_showThreads');
if(viewThreadedMenu)
viewThreadedMenu.setAttribute("hidden", "true");
var emptryTrashMenu = document.getElementById('menu_emptyTrash');
if(emptryTrashMenu)
emptryTrashMenu.setAttribute("hidden", "true");
var menuProperties = document.getElementById('menu_properties');
if(menuProperties)
menuProperties.setAttribute("hidden", "true");
var compactFolderMenu = document.getElementById('menu_compactFolder');
if(compactFolderMenu)
compactFolderMenu.setAttribute("hidden", "true");
var trashSeparator = document.getElementById('trashMenuSeparator');
if(trashSeparator)
trashSeparator.setAttribute("hidden", "true");
}
function OnUnloadMessageWindow()
{
// FIX ME - later we will be able to use onunload from the overlay
OnUnloadMsgHeaderPane();
OnMailWindowUnload();
}
function CreateMessageWindowGlobals()
{
gCompositeDataSource = Components.classes[compositeDataSourceContractID].createInstance();
gCompositeDataSource = gCompositeDataSource.QueryInterface(Components.interfaces.nsIRDFCompositeDataSource);
}
function InitializeDataSources()
{
AddDataSources();
//Now add datasources to composite datasource
gCompositeDataSource.AddDataSource(accountManagerDataSource);
gCompositeDataSource.AddDataSource(folderDataSource);
}
function GetSelectedMsgFolders()
{
var folderArray = new Array(1);
var msgFolder = GetLoadedMsgFolder();
if(msgFolder)
{
folderArray[0] = msgFolder;
}
return folderArray;
}
function GetFirstSelectedMessage()
{
return GetLoadedMessage();
}
function GetNumSelectedMessages()
{
if(gCurrentMessageUri)
return 1;
else
return 0;
}
function GetSelectedMessages()
{
var messageArray = new Array(1);
var message = GetLoadedMessage();
if(message) {
messageArray[0] = message;
}
return messageArray;
}
function GetSelectedIndices(dbView)
{
try {
var indicesArray = {};
var length = {};
dbView.getIndicesForSelection(indicesArray,length);
return indicesArray.value;
}
catch (ex) {
dump("ex = " + ex + "\n");
return null;
}
}
function GetLoadedMsgFolder()
{
if(gCurrentFolderUri)
{
var folderResource = RDF.GetResource(gCurrentFolderUri);
if(folderResource)
{
var msgFolder = folderResource.QueryInterface(Components.interfaces.nsIMsgFolder);
return msgFolder;
}
}
return null;
}
function GetLoadedMessage()
{
return gCurrentMessageUri;
}
//Clear everything related to the current message. called after load start page.
function ClearMessageSelection()
{
gCurrentMessageUri = null;
gCurrentFolderUri = null;
UpdateMailToolbar("clear msg, std alone window");
}
function GetCompositeDataSource(command)
{
return gCompositeDataSource;
}
function SetNextMessageAfterDelete()
{
gNextMessageViewIndexAfterDelete = gDBView.msgToSelectAfterDelete;
}
function SelectFolder(folderUri)
{
gCurrentFolderUri = folderUri;
}
function GetMsgHdrFromUri(messageUri)
{
return messenger.messageServiceFromURI(messageUri).messageURIToMsgHdr(messageUri);
}
function SelectMessage(messageUri)
{
var msgHdr = GetMsgHdrFromUri(messageUri);
gDBView.loadMessageByMsgKey(msgHdr.messageKey);
}
function ReloadMessage()
{
gDBView.reloadMessage();
}
function MsgDeleteMessageFromMessageWindow(reallyDelete, fromToolbar)
{
// if from the toolbar, return right away if this is a news message
// only allow cancel from the menu: "Edit | Cancel / Delete Message"
if (fromToolbar)
{
if (isNewsURI(gCurrentFolderUri))
{
// if news, don't delete
return;
}
}
// before we delete
SetNextMessageAfterDelete();
if (reallyDelete)
gDBView.doCommand(nsMsgViewCommandType.deleteNoTrash);
else
gDBView.doCommand(nsMsgViewCommandType.deleteMsg);
}
// MessageWindowController object (handles commands when one of the trees does not have focus)
var MessageWindowController =
{
supportsCommand: function(command)
{
switch ( command )
{
case "cmd_close":
case "cmd_reply":
case "button_reply":
case "cmd_replySender":
case "cmd_replyGroup":
case "cmd_replyall":
case "button_replyall":
case "cmd_forward":
case "button_forward":
case "cmd_forwardInline":
case "cmd_forwardAttachment":
case "cmd_editAsNew":
case "cmd_createFilterFromPopup":
case "cmd_createFilterFromMenu":
case "cmd_delete":
case "cmd_undo":
case "cmd_redo":
case "cmd_killThread":
case "cmd_watchThread":
case "button_delete":
case "cmd_shiftDelete":
case "button_print":
case "cmd_print":
case "cmd_printSetup":
case "cmd_saveAsFile":
case "cmd_saveAsTemplate":
case "cmd_viewPageSource":
case "cmd_reload":
case "cmd_getNewMessages":
case "button_getNewMessages":
case "cmd_getMsgsForAuthAccounts":
case "cmd_getNextNMessages":
case "cmd_find":
case "cmd_findAgain":
case "cmd_search":
case "button_mark":
case "cmd_markAsRead":
case "cmd_markAllRead":
case "cmd_markThreadAsRead":
case "cmd_markAsFlagged":
case "cmd_label0":
case "cmd_label1":
case "cmd_label2":
case "cmd_label3":
case "cmd_label4":
case "cmd_label5":
case "button_file":
case "cmd_file":
case "cmd_settingsOffline":
case "cmd_nextMsg":
case "button_next":
case "cmd_nextUnreadMsg":
case "cmd_nextFlaggedMsg":
case "cmd_nextUnreadThread":
case "cmd_previousMsg":
case "cmd_previousUnreadMsg":
case "cmd_previousFlaggedMsg":
return true;
case "cmd_synchronizeOffline":
case "cmd_downloadFlagged":
case "cmd_downloadSelected":
return CheckOnline();
default:
return false;
}
},
isCommandEnabled: function(command)
{
switch ( command )
{
case "cmd_createFilterFromPopup":
case "cmd_createFilterFromMenu":
var loadedFolder = GetLoadedMsgFolder();
if (!(loadedFolder && loadedFolder.server.canHaveFilters))
return false;
case "cmd_delete":
UpdateDeleteCommand();
// fall through
case "button_delete":
case "cmd_shiftDelete":
var loadedFolder = GetLoadedMsgFolder();
return gCurrentMessageUri && loadedFolder && loadedFolder.canDeleteMessages;
case "cmd_reply":
case "button_reply":
case "cmd_replySender":
case "cmd_replyGroup":
case "cmd_replyall":
case "button_replyall":
case "cmd_forward":
case "button_forward":
case "cmd_forwardInline":
case "cmd_forwardAttachment":
case "cmd_editAsNew":
case "cmd_print":
case "button_print":
case "cmd_saveAsFile":
case "cmd_saveAsTemplate":
case "cmd_viewPageSource":
case "cmd_reload":
case "cmd_find":
case "button_mark":
case "cmd_markAsRead":
case "cmd_markAllRead":
case "cmd_markThreadAsRead":
case "cmd_label0":
case "cmd_label1":
case "cmd_label2":
case "cmd_label3":
case "cmd_label4":
case "cmd_label5":
return(true);
case "cmd_markAsFlagged":
case "button_file":
case "cmd_file":
return ( gCurrentMessageUri != null);
case "cmd_printSetup":
return true;
case "cmd_getNewMessages":
case "button_getNewMessages":
case "cmd_getMsgsForAuthAccounts":
return IsGetNewMessagesEnabled();
case "cmd_getNextNMessages":
return IsGetNextNMessagesEnabled();
case "cmd_downloadFlagged":
case "cmd_downloadSelected":
case "cmd_synchronizeOffline":
return CheckOnline();
case "cmd_settingsOffline":
return IsAccountOfflineEnabled();
case "cmd_close":
case "cmd_nextMsg":
case "button_next":
case "cmd_nextUnreadMsg":
case "cmd_nextUnreadThread":
case "cmd_previousMsg":
case "cmd_previousUnreadMsg":
return true;
case "cmd_findAgain":
return MsgCanFindAgain();
case "cmd_search":
var loadedFolder = GetLoadedMsgFolder();
if (!loadedFolder)
return false;
return loadedFolder.server.canSearchMessages;
case "cmd_undo":
case "cmd_redo":
return SetupUndoRedoCommand(command);
default:
return false;
}
},
doCommand: function(command)
{
// if the user invoked a key short cut then it is possible that we got here for a command which is
// really disabled. kick out if the command should be disabled.
if (!this.isCommandEnabled(command)) return;
var navigationType = nsMsgNavigationType.nextUnreadMessage;
switch ( command )
{
case "cmd_close":
CloseMailWindow();
break;
case "cmd_getNewMessages":
MsgGetMessage();
break;
case "cmd_undo":
messenger.Undo(msgWindow);
break;
case "cmd_redo":
messenger.Redo(msgWindow);
break;
case "cmd_getMsgsForAuthAccounts":
MsgGetMessagesForAllAuthenticatedAccounts();
break;
case "cmd_getNextNMessages":
MsgGetNextNMessages();
break;
case "cmd_reply":
MsgReplyMessage(null);
break;
case "cmd_replySender":
MsgReplySender(null);
break;
case "cmd_replyGroup":
MsgReplyGroup(null);
break;
case "cmd_replyall":
MsgReplyToAllMessage(null);
break;
case "cmd_forward":
MsgForwardMessage(null);
break;
case "cmd_forwardInline":
MsgForwardAsInline(null);
break;
case "cmd_forwardAttachment":
MsgForwardAsAttachment(null);
break;
case "cmd_editAsNew":
MsgEditMessageAsNew();
break;
case "cmd_createFilterFromPopup":
break;// This does nothing because the createfilter is invoked from the popupnode oncommand.
case "cmd_createFilterFromMenu":
MsgCreateFilter();
break;
case "cmd_delete":
MsgDeleteMessageFromMessageWindow(false, false);
break;
case "cmd_shiftDelete":
MsgDeleteMessageFromMessageWindow(true, false);
break;
case "button_delete":
MsgDeleteMessageFromMessageWindow(false, true);
break;
case "cmd_printSetup":
goPageSetup();
break;
case "cmd_print":
PrintEnginePrint();
break;
case "cmd_saveAsFile":
MsgSaveAsFile();
break;
case "cmd_saveAsTemplate":
MsgSaveAsTemplate();
break;
case "cmd_viewPageSource":
MsgViewPageSource();
break;
case "cmd_reload":
MsgReload();
break;
case "cmd_find":
MsgFind();
break;
case "cmd_findAgain":
MsgFindAgain();
break;
case "cmd_search":
MsgSearchMessages();
break;
case "button_mark":
case "cmd_markAsRead":
MsgMarkMsgAsRead(null);
return;
case "cmd_markThreadAsRead":
MsgMarkThreadAsRead();
return;
case "cmd_markAllRead":
MsgMarkAllRead();
return;
case "cmd_markAsFlagged":
MsgMarkAsFlagged(null);
return;
case "cmd_label0":
gDBView.doCommand(nsMsgViewCommandType.label0);
return;
case "cmd_label1":
gDBView.doCommand(nsMsgViewCommandType.label1);
return;
case "cmd_label2":
gDBView.doCommand(nsMsgViewCommandType.label2);
return;
case "cmd_label3":
gDBView.doCommand(nsMsgViewCommandType.label3);
return;
case "cmd_label4":
gDBView.doCommand(nsMsgViewCommandType.label4);
return;
case "cmd_label5":
gDBView.doCommand(nsMsgViewCommandType.label5);
return;
case "cmd_downloadFlagged":
MsgDownloadFlagged();
return;
case "cmd_downloadSelected":
MsgDownloadSelected();
return;
case "cmd_synchronizeOffline":
MsgSynchronizeOffline();
return;
case "cmd_settingsOffline":
MsgSettingsOffline();
return;
case "cmd_nextUnreadMsg":
case "button_next":
performNavigation(nsMsgNavigationType.nextUnreadMessage);
break;
case "cmd_nextUnreadThread":
performNavigation(nsMsgNavigationType.nextUnreadThread);
break;
case "cmd_nextMsg":
performNavigation(nsMsgNavigationType.nextMessage);
break;
case "cmd_nextFlaggedMsg":
performNavigation(nsMsgNavigationType.nextFlagged);
break;
case "cmd_previousMsg":
performNavigation(nsMsgNavigationType.previousMessage);
break;
case "cmd_previousUnreadMsg":
performNavigation(nsMsgNavigationType.previousUnreadMessage);
break;
case "cmd_previousFlaggedMsg":
performNavigation(nsMsgNavigationType.previousFlagged);
break;
}
},
onEvent: function(event)
{
}
};
function performNavigation(type)
{
var resultId = new Object;
var resultIndex = new Object;
var threadIndex = new Object;
gDBView.viewNavigate(type, resultId, resultIndex, threadIndex, true /* wrap */);
// if we found something....display it.
if ((resultId.value != nsMsgKey_None) && (resultIndex.value != nsMsgKey_None))
{
// load the message key
gDBView.loadMessageByMsgKey(resultId.value);
// if we changed folders, the message counts changed.
UpdateStandAloneMessageCounts();
return;
}
// we need to span another folder
CrossFolderNavigation(type, false);
}
function SetupCommandUpdateHandlers()
{
top.controllers.insertControllerAt(0, MessageWindowController);
}
function GetDBView()
{
return gDBView;
}