?? msgmail3panewindow.js
字號:
var folderResource = GetFolderResource(folderTree, index); if (folderTree.view.getLevel(index) == 0) { // (Imap/Nntp/Pop) Account item. folderResource.QueryInterface(Components.interfaces.nsIMsgFolder) .server.performExpand(msgWindow); } else if (folderResource instanceof Components.interfaces.nsIMsgImapMailFolder) { // Imap message folder item. folderResource.performExpand(msgWindow); } }, onCycleHeader: function(colID, elt) { }, onCycleCell: function(row, colID) { }, onSelectionChanged: function() { }, onPerformAction: function(action) { }, onPerformActionOnRow: function(action, row) { }, onPerformActionOnCell: function(action, row, col) { }}function HandleDeleteOrMoveMsgFailed(folder){ gDBView.onDeleteCompleted(false); if(IsCurrentLoadedFolder(folder)) { if(gNextMessageAfterDelete) { gNextMessageAfterDelete = null; gNextMessageViewIndexAfterDelete = -2; } } // fix me??? // ThreadPaneSelectionChange(true);}// WARNING// this is a fragile and complicated function.// be careful when hacking on it.// don't forget about things like different imap // delete models, multiple views (from multiple thread panes, // search windows, stand alone message windows)function HandleDeleteOrMoveMsgCompleted(folder){ // you might not have a db view. this can happen if // biff fires when the 3 pane is set to account central. if (!gDBView) return; gDBView.onDeleteCompleted(true); if (!IsCurrentLoadedFolder(folder)) { // default value after delete/move/copy is over gNextMessageViewIndexAfterDelete = -2; return; } var treeView = gDBView.QueryInterface(Components.interfaces.nsITreeView); var treeSelection = treeView.selection; if (gNextMessageViewIndexAfterDelete == -2) { // a move or delete can cause our selection can change underneath us. // this can happen when the user // deletes message from the stand alone msg window // or the search view, or another 3 pane if (treeSelection.count == 0) { // this can happen if you double clicked a message // in the thread pane, and deleted it from the stand alone msg window // see bug #172392 treeSelection.clearSelection(); setTitleFromFolder(folder, null); UpdateMailToolbar("delete from another view, 0 rows now selected"); } else if (treeSelection.count == 1) { // this can happen if you had two messages selected // in the thread pane, and you deleted one of them from another view // (like the view in the stand alone msg window) // since one item is selected, we should load it. var startIndex = {}; var endIndex = {}; treeSelection.getRangeAt(0, startIndex, endIndex); // select the selected item, so we'll load it treeSelection.select(startIndex.value); treeView.selectionChanged(); EnsureRowInThreadTreeIsVisible(startIndex.value); UpdateMailToolbar("delete from another view, 1 row now selected"); } else { // this can happen if you have more than 2 messages selected // in the thread pane, and you deleted one of them from another view // (like the view in the stand alone msg window) // since multiple messages are still selected, do nothing. } } else { if (gNextMessageViewIndexAfterDelete != nsMsgViewIndex_None) { var viewSize = treeView.rowCount; if (gNextMessageViewIndexAfterDelete >= viewSize) { if (viewSize > 0) gNextMessageViewIndexAfterDelete = viewSize - 1; else { gNextMessageViewIndexAfterDelete = nsMsgViewIndex_None; // there is nothing to select since viewSize is 0 treeSelection.clearSelection(); setTitleFromFolder(folder, null); ClearMessagePane(); UpdateMailToolbar("delete from current view, 0 rows left"); } } } // if we are about to set the selection with a new element then DON'T clear // the selection then add the next message to select. This just generates // an extra round of command updating notifications that we are trying to // optimize away. if (gNextMessageViewIndexAfterDelete != nsMsgViewIndex_None) { // when deleting a message we don't update the commands // when the selection goes to 0 // (we have a hack in nsMsgDBView which prevents that update) // so there is no need to // update commands when we select the next message after the delete; // the commands already // have the right update state... gDBView.suppressCommandUpdating = true; // This check makes sure that the tree does not perform a // selection on a non selected row (row < 0), else assertions will // be thrown. if (gNextMessageViewIndexAfterDelete >= 0) treeSelection.select(gNextMessageViewIndexAfterDelete); // if gNextMessageViewIndexAfterDelete has the same value // as the last index we had selected, the tree won't generate a // selectionChanged notification for the tree view. So force a manual // selection changed call. // (don't worry it's cheap if we end up calling it twice). if (treeView) treeView.selectionChanged(); EnsureRowInThreadTreeIsVisible(gNextMessageViewIndexAfterDelete); gDBView.suppressCommandUpdating = false; // hook for extra toolbar items // XXX TODO // I think there is a bug in the suppression code above. // what if I have two rows selected, and I hit delete, // and so we load the next row. // what if I have commands that only enable where // exactly one row is selected? UpdateMailToolbar("delete from current view, at least one row selected"); } } // default value after delete/move/copy is over gNextMessageViewIndexAfterDelete = -2;}function HandleCompactCompleted(folder){ if (folder) { var resource = folder.QueryInterface(Components.interfaces.nsIRDFResource); if (resource) { var uri = resource.Value; var msgFolder = msgWindow.openFolder; if (msgFolder && uri == msgFolder.URI) { var msgdb = msgFolder.getMsgDatabase(msgWindow); if (msgdb) { var dbFolderInfo = msgdb.dBFolderInfo; sortType = dbFolderInfo.sortType; sortOrder = dbFolderInfo.sortOrder; viewFlags = dbFolderInfo.viewFlags; viewType = dbFolderInfo.viewType; dbFolderInfo = null; } RerootFolder(uri, msgFolder, viewType, viewFlags, sortType, sortOrder); LoadCurrentlyDisplayedMessage(); } } }}function LoadCurrentlyDisplayedMessage(){ if (gCurrentlyDisplayedMessage != nsMsgViewIndex_None) { var treeView = gDBView.QueryInterface(Components.interfaces.nsITreeView); var treeSelection = treeView.selection; treeSelection.select(gCurrentlyDisplayedMessage); if (treeView) treeView.selectionChanged(); EnsureRowInThreadTreeIsVisible(gCurrentlyDisplayedMessage); SetFocusThreadPane(); gCurrentlyDisplayedMessage = nsMsgViewIndex_None; //reset }}function IsCurrentLoadedFolder(folder){ var msgfolder = folder.QueryInterface(Components.interfaces.nsIMsgFolder); if(msgfolder) { var folderResource = msgfolder.QueryInterface(Components.interfaces.nsIRDFResource); if(folderResource) { var folderURI = folderResource.Value; var currentLoadedFolder = GetThreadPaneFolder(); if (currentLoadedFolder.flags & MSG_FOLDER_FLAG_VIRTUAL) { var msgDatabase = currentLoadedFolder.getMsgDatabase(msgWindow); var dbFolderInfo = msgDatabase.dBFolderInfo; var srchFolderUri = dbFolderInfo.getCharPtrProperty("searchFolderUri"); var re = new RegExp("^" + folderURI + "$|^" + folderURI + "\||\|" + folderURI + "$|\|" + folderURI +"\|"); var retval = (currentLoadedFolder.URI.match(re)); return retval; } var currentURI = currentLoadedFolder.URI; return(currentURI == folderURI); } } return false;}function ServerContainsFolder(server, folder){ if (!folder || !server) return false; return server.equals(folder.server);}function SelectServer(server){ SelectFolder(server.rootFolder.URI);}// we have this incoming server listener in case we need to// alter the folder pane selection when a server is removed// or changed (currently, when the real username or real hostname change)var gThreePaneIncomingServerListener = { onServerLoaded: function(server) {}, onServerUnloaded: function(server) { var selectedFolders = GetSelectedMsgFolders(); for (var i = 0; i < selectedFolders.length; i++) { if (ServerContainsFolder(server, selectedFolders[i])) { SelectServer(accountManager.defaultAccount.incomingServer); // we've made a new selection, we're done return; } } // if nothing is selected at this point, better go select the default // this could happen if nothing was selected when the server was removed selectedFolders = GetSelectedMsgFolders(); if (selectedFolders.length == 0) { SelectServer(accountManager.defaultAccount.incomingServer); } }, onServerChanged: function(server) { // if the current selected folder is on the server that changed // and that server is an imap or news server, // we need to update the selection. // on those server types, we'll be reconnecting to the server // and our currently selected folder will need to be reloaded // or worse, be invalid. if (server.type != "imap" && server.type !="nntp") return; var selectedFolders = GetSelectedMsgFolders(); for (var i = 0; i < selectedFolders.length; i++) { // if the selected item is a server, we don't have to update // the selection if (!(selectedFolders[i].isServer) && ServerContainsFolder(server, selectedFolders[i])) { SelectServer(server); // we've made a new selection, we're done return; } } }}// aMsgWindowInitialized: false if we are calling from the onload handler, otherwise truefunction UpdateMailPaneConfig(aMsgWindowInitialized) { var paneConfig = pref.getIntPref("mail.pane_config.dynamic"); if (paneConfig == kStandardPaneConfig) document.getElementById('messagepanebox').setAttribute('flex', 1); else document.getElementById('messagepanebox').removeAttribute('flex'); // don't do anything if we are already in the correct configuration if (paneConfig == gCurrentPaneConfig) return; var mailContentWrapper = document.getElementById("mailContentWrapper"); var messagesBox = document.getElementById("messagesBox"); var messengerBox = document.getElementById("messengerBox"); var messagePaneBox = GetMessagePane(); var msgPaneReRooted = false; var threadPaneSplitter = GetThreadAndMessagePaneSplitter(); // the only element we need to re-root is the message pane. var desiredMsgPaneParentId = (paneConfig == "0" || paneConfig == "2" || paneConfig == "3") ? "messagesBox" : "mailContentWrapper"; if (messagePaneBox.parentNode.id != desiredMsgPaneParentId) { var messagePaneParent = document.getElementById(messagePaneBox.parentNode.id); messagePaneParent.removeChild(threadPaneSplitter); messagePaneParent.removeChild(messagePaneBox); var messagePaneNewParent = document.getElementById(desiredMsgPaneParentId); messagePaneNewParent.appendChild(threadPaneSplitter); messagePaneNewParent.appendChild(messagePaneBox); msgPaneReRooted = true; } /* this code doesn't work yet, see the comment below about kWideThreadPaneConfig if (gCurrentPaneConfig == kWideThreadPaneConfig) { threadPaneSplitter.setAttribute("orient", "vertical"); mailContentWrapper.setAttribute("orient", "horizontal"); mailContentWrapper.removeChild(threadPaneSplitter); mailContentWrapper.removeChild(messagePaneBox); messagesBox.insertBefore(threadPaneSplitter, messagesBox.firstChild); messagesBox.insertBefore(messengerBox, messagesBox.firstChild); messagePaneBox.removeAttribute("flex"); msgPaneReRooted = true; } */ // now for each config, handle any extra clean up to create that view (such as changing a box orientation) if (paneConfig == kStandardPaneConfig) // standard 3-Pane Layout { threadPaneSplitter.setAttribute("orient", "vertical");
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -