fixing bug 30560 - right-clicking a mail message/folder should not display it. r=neil, sr=sspitzer, a=asa

This commit is contained in:
ssu%netscape.com 2002-03-14 02:40:51 +00:00
Родитель 89d50a8bbf
Коммит 218064aa3b
7 изменённых файлов: 194 добавлений и 29 удалений

Просмотреть файл

@ -654,16 +654,28 @@ function OnClickThreadAndMessagePaneSplitterGrippy()
function FolderPaneSelectionChange()
{
var folderOutliner = GetFolderOutliner();
var folderSelection = folderOutliner.outlinerBoxObject.selection;
// This prevents a folder from being loaded in the case that the user
// has right-clicked on a folder different from the one that was
// originally highlighted. On a right-click, the highlight (selection)
// of a row will be different from the value of currentIndex, thus if
// the currentIndex is not selected, it means the user right-clicked
// and we don't want to load the contents of the folder.
if (!folderSelection.isSelected(folderSelection.currentIndex))
return;
if(gTimelineEnabled) {
gTimelineService.startTimer("FolderLoading");
gTimelineService.enter("FolderLoading has Started");
}
var folderOutliner = GetFolderOutliner();
if (folderOutliner.outlinerBoxObject.selection.count == 1)
if (folderSelection.count == 1)
{
var startIndex = {};
var endIndex = {};
folderOutliner.outlinerBoxObject.selection.getRangeAt(0, startIndex, endIndex);
folderSelection.getRangeAt(0, startIndex, endIndex);
var folderResource = GetFolderResource(folderOutliner, startIndex.value);
var msgFolder = folderResource.QueryInterface(Components.interfaces.nsIMsgFolder);
if (msgFolder == msgWindow.openFolder)

Просмотреть файл

@ -25,6 +25,45 @@
//NOTE: gMessengerBundle must be defined and set or this Overlay won't work
// Function to change the highlighted row back to the row that is currently
// outline/dotted without loading the contents of either rows. This is
// triggered when the context menu for a given row is hidden/closed
// (onpopuphiding).
function RestoreSelectionWithoutContentLoad(outliner)
{
var outlinerBoxObj = outliner.outlinerBoxObject;
var outlinerSelection = outlinerBoxObj.selection;
if((!outlinerSelection.isSelected(outlinerSelection.currentIndex)) &&
(outlinerSelection.currentIndex >= 0))
{
outlinerSelection.selectEventsSuppressed = true;
outlinerSelection.select(outlinerSelection.currentIndex);
outlinerSelection.selectEventsSuppressed = false;
// Keep track of which row in the thread pane is currently selected.
// This is currently only needed when deleting messages. See
// declaration of var in msgMail3PaneWindow.js.
if(outliner.id == "threadOutliner")
gThreadPaneCurrentSelectedIndex = outlinerSelection.currentIndex;
}
else if(!gThreadPaneDeleteOrMoveOccurred && (outlinerSelection.currentIndex < 0))
// Clear the selection in the case of when a folder has just been
// loaded where the message pane does not have a message loaded yet.
// When right-clicking a message in this case and dismissing the
// popup menu (by either executing a menu command or clicking
// somewhere else), the selection needs to be cleared.
// However, if the 'Delete Message' or 'Move To' menu item has been
// selected, DO NOT clear the selection, else it will prevent the
// outliner view from refreshing.
outlinerSelection.clearSelection();
}
function threadPaneOnPopupHiding()
{
RestoreSelectionWithoutContentLoad(GetThreadOutliner());
}
function fillThreadPaneContextMenu()
{
var numSelected = GetNumSelectedMessages();
@ -32,6 +71,10 @@ function fillThreadPaneContextMenu()
var isNewsgroup = false;
var selectedMessage = null;
// Clear the global var used to keep track if a 'Delete Message' or 'Move
// To' command has been triggered via the thread pane context menu.
gThreadPaneDeleteOrMoveOccurred = false;
if(numSelected >= 0) {
selectedMessage = GetFirstSelectedMessage();
isNewsgroup = IsNewsMessage(selectedMessage);
@ -54,9 +97,10 @@ function fillThreadPaneContextMenu()
SetupCopyMessageUrlMenuItem("threadPaneContext-copyMessageUrl", numSelected, isNewsgroup, numSelected != 1);
SetupCopyMenuItem("threadPaneContext-copyMenu", numSelected, false);
SetupMoveMenuItem("threadPaneContext-moveMenu", numSelected, isNewsgroup, false);
EnableMenuItem("threadPaneContext-labels", (numSelected >= 1));
SetupSaveAsMenuItem("threadPaneContext-saveAs", numSelected, false);
SetupPrintMenuItem("threadPaneContext-print", numSelected, false);
goUpdateCommand('cmd_delete');
SetupDeleteMenuItem("threadPaneContext-delete", numSelected, false);
SetupAddSenderToABMenuItem("threadPaneContext-addSenderToAddressBook", numSelected, false);
SetupAddAllToABMenuItem("threadPaneContext-addAllToAddressBook", numSelected, false);
@ -156,6 +200,22 @@ function SetupAddAllToABMenuItem(menuID, numSelected, forceHide)
EnableMenuItem(menuID, false);
}
function SetupDeleteMenuItem(menuID, numSelected, forceHide)
{
// This function is needed for the case where a folder is just loaded (while
// there isn't a message loaded in the message pane), a right-click is done
// in the thread pane. This function will disable enable the 'Delete
// Message' menu item.
ShowMenuItem(menuID, !forceHide);
EnableMenuItem(menuID, (numSelected > 0));
goUpdateCommand('cmd_delete');
}
function folderPaneOnPopupHiding()
{
RestoreSelectionWithoutContentLoad(GetFolderOutliner());
}
function fillFolderPaneContextMenu()
{
var folderOutliner = GetFolderOutliner();

Просмотреть файл

@ -912,11 +912,12 @@ function MsgOpenNewWindowForFolder(uri, key)
var keyToSelect = key;
if (!uriToOpen)
{
var folder = GetLoadedMsgFolder();
var folderResource = folder.QueryInterface(Components.interfaces.nsIRDFResource);
uriToOpen = folderResource.Value;
}
// use GetSelectedFolderURI() to find out which message to open instead of
// GetLoadedMsgFolder().QueryIntervace(Components.interfaces.nsIRDFResource).value.
// This is required because on a right-click, the currentIndex value will be
// different from the actual row that is highlighted. GetSelectedFolderURI()
// will return the message that is highlighted.
uriToOpen = GetSelectedFolderURI();
if (uriToOpen) {
var layoutType = gPrefs.getIntPref("mail.pane_config");
@ -942,21 +943,23 @@ function MsgOpenSelectedMessages()
function MsgOpenNewWindowForMessage(messageUri, folderUri)
{
var currentIndex;
if (!messageUri)
// use GetFirstSelectedMessage() to find out which message to open
// instead of gDBView.getURIForViewIndex(currentIndex). This is
// required because on a right-click, the currentIndex value will be
// different from the actual row that is highlighted.
// GetFirstSelectedMessage() will return the message that is
// highlighted.
messageUri = GetFirstSelectedMessage();
if (!messageUri || !folderUri) {
var outlinerView = gDBView.QueryInterface(Components.interfaces.nsIOutlinerView);
var outlinerSelection = outlinerView.selection;
currentIndex = outlinerSelection.currentIndex;
}
if (!messageUri) {
messageUri = gDBView.getURIForViewIndex(currentIndex);
}
if (!folderUri) {
folderUri = gDBView.getFolderForViewIndex(currentIndex).URI;
}
if (!folderUri)
// use GetSelectedFolderURI() to find out which message to open
// instead of gDBView.getURIForViewIndex(currentIndex). This is
// required because on a right-click, the currentIndex value will be
// different from the actual row that is highlighted.
// GetSelectedFolderURI() will return the message that is
// highlighted.
folderUri = GetSelectedFolderURI();
// be sure to pass in the current view....
if (messageUri && folderUri) {

Просмотреть файл

@ -336,7 +336,8 @@ Rights Reserved.
</keyset>
<popup id="threadPaneContext" onpopupshowing="return fillThreadPaneContextMenu();" >
<popup id="threadPaneContext" onpopupshowing="return fillThreadPaneContextMenu();"
onpopuphiding="if (event.target == this) threadPaneOnPopupHiding();">
<menuitem id="threadPaneContext-openNewWindow"
label="&contextOpenNewWindow.label;"
accesskey="&contextOpenNewWindow.accesskey;"
@ -551,8 +552,9 @@ Rights Reserved.
command="cmd_delete"/>
</popup>
<popup id="folderPaneContext" onpopupshowing="return fillFolderPaneContextMenu();" >
<menuitem id="folderPaneContext-openNewWindow"
<popup id="folderPaneContext" onpopupshowing="return fillFolderPaneContextMenu();"
onpopuphiding="if (event.target == this) folderPaneOnPopupHiding();">
<menuitem id="folderPaneContext-openNewWindow"
label="&folderContextOpenNewWindow.label;"
accesskey="&folderContextOpenNewWindow.accesskey;"
oncommand="MsgOpenNewWindowForFolder(null,-1);"/>

Просмотреть файл

@ -53,6 +53,16 @@ var gCurrentlyDisplayedMessage=nsMsgViewIndex_None;
var gStartFolderUri = null;
var gStartMsgKey = -1;
// Global var to keep track of which row in the thread pane has been selected
// This is used to make sure that the row with the currentIndex has the selection
// after a Delete or Move of a message that has a row index less than currentIndex.
var gThreadPaneCurrentSelectedIndex = -1;
// Global var to keep track of if the 'Delete Message' or 'Move To' thread pane
// context menu item was triggered. This helps prevent the outliner view from
// not updating on one of those menu item commands.
var gThreadPaneDeleteOrMoveOccurred = false;
//If we've loaded a message, set to true. Helps us keep the start page around.
var gHaveLoadedMessage;
@ -298,7 +308,12 @@ function HandleDeleteOrMoveMsgCompleted(folder)
// update commands when we select the next message after the delete; the commands already
// have the right update state...
gDBView.suppressCommandUpdating = true;
outlinerSelection.select(gNextMessageViewIndexAfterDelete);
// This check makes sure that the outliner does not perform a
// selection on a non selected row (row < 0), else assertions will
// be thrown.
if (gNextMessageViewIndexAfterDelete >= 0)
outlinerSelection.select(gNextMessageViewIndexAfterDelete);
// if gNextMessageViewIndexAfterDelete has the same value
// as the last index we had selected, the outliner won't generate a
@ -706,6 +721,7 @@ function OnLoadFolderPane()
var folderOutlinerBuilder = folderOutliner.builder.QueryInterface(Components.interfaces.nsIXULOutlinerBuilder);
folderOutlinerBuilder.addObserver(folderObserver);
folderOutliner.addEventListener("click",FolderPaneOnClick,true);
folderOutliner.addEventListener("mousedown",OutlinerOnMouseDown,true);
}
// builds prior to 12-08-2001 did not have the labels column
@ -872,6 +888,43 @@ function GetSelectedFolderIndex()
return startIndex.value;
}
// Function to change the highlighted row to where the mouse was clicked
// without loading the contents of the selected row.
// It will also keep the outline/dotted line in the original row.
function ChangeSelectionWithoutContentLoad(event, outliner)
{
var row = {};
var col = {};
var elt = {};
var outlinerBoxObj = outliner.outlinerBoxObject;
var outlinerSelection = outlinerBoxObj.selection;
outlinerBoxObj.getCellAt(event.clientX, event.clientY, row, col, elt);
if((row.value >= 0) && !outlinerSelection.isSelected(row.value))
{
var saveCurrentIndex = outlinerSelection.currentIndex;
outlinerSelection.selectEventsSuppressed = true;
outlinerSelection.select(row.value);
outlinerSelection.currentIndex = saveCurrentIndex;
outlinerBoxObj.ensureRowIsVisible(row.value);
outlinerSelection.selectEventsSuppressed = false;
// Keep track of which row in the thread pane is currently selected.
if(outliner.id == "threadOutliner")
gThreadPaneCurrentSelectedIndex = row.value;
}
event.preventBubble();
}
function OutlinerOnMouseDown(event)
{
// Detect right mouse click and change the highlight to the row
// where the click happened without loading the message headers in
// the Folder or Thread Pane.
if (event.button == 2)
ChangeSelectionWithoutContentLoad(event, event.target.parentNode);
}
function FolderPaneOnClick(event)
{
// we only care about button 0 (left click) events
@ -1011,7 +1064,10 @@ function GetSelectedMsgFolders()
function GetFirstSelectedMessage()
{
try {
return gDBView.URIForFirstSelectedMessage;
// Use this instead of gDBView.URIForFirstSelectedMessage, else it
// will return the currentIndex message instead of the highlighted
// message.
return GetSelectedMessages()[0];
}
catch (ex) {
return null;
@ -1078,7 +1134,22 @@ function GetCompositeDataSource(command)
function SetNextMessageAfterDelete()
{
var outlinerSelection = GetThreadOutliner().outlinerBoxObject.selection;
gThreadPaneDeleteOrMoveOccurred = true;
if (outlinerSelection.isSelected(outlinerSelection.currentIndex))
gNextMessageViewIndexAfterDelete = gDBView.msgToSelectAfterDelete;
else if (outlinerSelection.currentIndex > gThreadPaneCurrentSelectedIndex)
// Since the currentIndex (the row with the outline/dotted line) is greater
// than the currently selected row (the row that is highlighted), we need to
// make sure that upon a Delete or Move of the selected row, the highlight
// returns to the currentIndex'ed row. It is necessary to subtract 1
// because the row being deleted is above the row with the currentIndex.
// If the subtraction is not done, then the highlight will end up on the
// row listed after the currentIndex'ed row.
gNextMessageViewIndexAfterDelete = outlinerSelection.currentIndex - 1;
else
gNextMessageViewIndexAfterDelete = outlinerSelection.currentIndex;
}
function EnsureAllAncestorsAreExpanded(outliner, resource)

Просмотреть файл

@ -312,7 +312,24 @@ function EnsureRowInThreadOutlinerIsVisible(index)
function ThreadPaneOnLoad()
{
var outliner = GetThreadOutliner();
outliner.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(outliner.parentNode.id == "searchResultListBox")
return;
outliner.addEventListener("mousedown",OutlinerOnMouseDown,true);
}
function ThreadPaneSelectionChanged()
{
var outlinerBoxObj = GetThreadOutliner().outlinerBoxObject;
var outlinerSelection = outlinerBoxObj.selection;
if (outlinerSelection.isSelected(outlinerSelection.currentIndex))
outlinerBoxObj.view.selectionChanged();
}
addEventListener("load",ThreadPaneOnLoad,true);

Просмотреть файл

@ -32,7 +32,7 @@ Rights Reserved.
<outliner id="threadOutliner" flex="1" enableColumnDrag="true" class="plain"
onkeypress="ThreadPaneKeyPress(event);"
onselect="this.outlinerBoxObject.view.selectionChanged();">
onselect="ThreadPaneSelectionChanged();">
<outlinercols>
<outlinercol id="threadCol" display="&threadColumn.label;" class="outlinercol-image threadColumnHeader" currentView="unthreaded" cycler="true" persist="hidden ordinal" fixed="true" />
<outlinercol id="subjectCol" class="sortDirectionIndicator" persist="hidden ordinal width" flex="7" label="&subjectColumn.label;" primary="true"/>