diff --git a/mail/base/content/mail3PaneWindowCommands.js b/mail/base/content/mail3PaneWindowCommands.js index af25a5006a..50c69e6f51 100644 --- a/mail/base/content/mail3PaneWindowCommands.js +++ b/mail/base/content/mail3PaneWindowCommands.js @@ -310,18 +310,29 @@ var DefaultController = case "cmd_viewPageSource": case "cmd_reload": case "cmd_applyFiltersToSelection": + let numSelected = GetNumSelectedMessages(); if (command == "cmd_applyFiltersToSelection") { var whichText = "valueMessage"; - if (GetNumSelectedMessages() > 1) + if (numSelected > 1) whichText = "valueSelection"; goSetMenuValue(command, whichText); goSetAccessKey(command, whichText + "AccessKey"); } - if (GetNumSelectedMessages() > 0) + if (numSelected > 0) { if (!gFolderDisplay.getCommandStatus(nsMsgViewCommandType.cmdRequiringMsgBody)) return false; + + // Check if we have a collapsed thread selected and are summarizing it. + // If so, selectedIndices.length won't match numSelected. Also check + // that we're not displaying a message, which handles the case + // where we failed to summarize the selection and fell back to + // displaying a message. + if (gFolderDisplay.selectedIndices.length != numSelected && + command != "cmd_applyFiltersToSelection" && + gDBView && gDBView.currentlyDisplayedMessage == nsMsgViewIndex_None) + return false; if (command == "cmd_reply" || command == "button_reply" || command == "cmd_replyall" ||command == "button_replyall") return IsReplyEnabled(); diff --git a/mailnews/base/public/nsIMsgDBView.idl b/mailnews/base/public/nsIMsgDBView.idl index 2ece231aa5..bb63646c64 100644 --- a/mailnews/base/public/nsIMsgDBView.idl +++ b/mailnews/base/public/nsIMsgDBView.idl @@ -332,7 +332,12 @@ interface nsIMsgDBView : nsISupports * If the "mail.operate_on_msgs_in_collapsed_threads" preference is enabled, * then any collapsed thread roots that are selected will also (conceptually) * have all of the messages in that thread selected and they will be included - * in the returned list. + * in the returned list. The one exception to this is if the front end fails + * to summarize the selection, and we fall back to just displaying a single + * message. In that case, we won't include the children of the collapsed + * thread. However, the numSelected attribute will count those children, + * because the summarizeSelection code uses that to know that it should + * try to summarize the selection. * * If the user has right-clicked on a message, this will return that message * (and any collapsed children if so enabled) and not the selection prior to diff --git a/mailnews/base/src/nsMsgDBView.cpp b/mailnews/base/src/nsMsgDBView.cpp index 02f75e16a1..e33273b31f 100644 --- a/mailnews/base/src/nsMsgDBView.cpp +++ b/mailnews/base/src/nsMsgDBView.cpp @@ -163,6 +163,8 @@ nsMsgDBView::nsMsgDBView() mSuppressMsgDisplay = PR_FALSE; mSuppressCommandUpdating = PR_FALSE; mSuppressChangeNotification = PR_FALSE; + mSummarizeFailed = PR_FALSE; + mSelectionSummarized = PR_FALSE; mGoForwardEnabled = PR_FALSE; mGoBackEnabled = PR_FALSE; @@ -1047,11 +1049,25 @@ NS_IMETHODIMP nsMsgDBView::SelectionChanged() commandsNeedDisablingBecauseOfSelection = PR_TRUE; } PRBool selectionSummarized = PR_FALSE; + mSummarizeFailed = PR_FALSE; // let the front-end adjust the message pane appropriately with either // the message body, or a summary of the selection if (mCommandUpdater) + { mCommandUpdater->SummarizeSelection(&selectionSummarized); + // check if the selection was not summarized, but we expected it to be, + // and if so, remember it so GetHeadersFromSelection won't include + // the messages in collapsed threads. + if (!selectionSummarized && + (numSelected > 1 || (numSelected == 1 && + m_flags[indices[0]] & nsMsgMessageFlags::Elided && + OperateOnMsgsInCollapsedThreads()))) + mSummarizeFailed = PR_TRUE; + } + PRBool summaryStateChanged = selectionSummarized != mSelectionSummarized; + + mSelectionSummarized = selectionSummarized; // if only one item is selected then we want to display a message if (numSelected == 1 && !selectionSummarized) { @@ -1089,6 +1105,7 @@ NS_IMETHODIMP nsMsgDBView::SelectionChanged() // (4) it went from many to 1 or 0 // (5) a different msg was selected - perhaps it was offline or not...matters only when we are offline // (6) we did a forward/back, or went from having no history to having history - not sure how to tell this. + // (7) whether the selection was summarized or not changed. // I think we're going to need to keep track of whether forward/back were enabled/should be enabled, // and when this changes, force a command update. @@ -1098,7 +1115,8 @@ NS_IMETHODIMP nsMsgDBView::SelectionChanged() NavigateStatus(nsMsgNavigationType::forward, &enableGoForward); NavigateStatus(nsMsgNavigationType::back, &enableGoBack); - if ((numSelected == mNumSelectedRows || + if (!summaryStateChanged && + (numSelected == mNumSelectedRows || (numSelected > 1 && mNumSelectedRows > 1)) && (commandsNeedDisablingBecauseOfSelection == mCommandsNeedDisablingBecauseOfSelection) && enableGoForward == mGoForwardEnabled && enableGoBack == mGoBackEnabled) { @@ -2535,6 +2553,7 @@ PRBool nsMsgDBView::OperateOnMsgsInCollapsedThreads() if (!selTree) return PR_FALSE; } + nsresult rv = NS_OK; nsCOMPtr prefBranch (do_GetService(NS_PREFSERVICE_CONTRACTID, &rv)); NS_ENSURE_SUCCESS(rv, PR_FALSE); @@ -2550,7 +2569,10 @@ nsresult nsMsgDBView::GetHeadersFromSelection(PRUint32 *indices, { nsresult rv = NS_OK; - PRBool includeCollapsedMsgs = OperateOnMsgsInCollapsedThreads(); + // Don't include collapsed messages if the front end failed to summarize + // the selection. + PRBool includeCollapsedMsgs = OperateOnMsgsInCollapsedThreads() && + !mSummarizeFailed; for (PRUint32 index = 0; index < (nsMsgViewIndex) numIndices && NS_SUCCEEDED(rv); index++) diff --git a/mailnews/base/src/nsMsgDBView.h b/mailnews/base/src/nsMsgDBView.h index 8634348dfb..b89a3178a9 100644 --- a/mailnews/base/src/nsMsgDBView.h +++ b/mailnews/base/src/nsMsgDBView.h @@ -445,6 +445,9 @@ protected: PRPackedBool mIsNews; // we have special icons for news PRPackedBool mShowSizeInLines; // for news we show lines instead of size when true PRPackedBool m_sortValid; + PRPackedBool mSelectionSummarized; + // we asked the front end to summarize the selection and it did not. + PRPackedBool mSummarizeFailed; PRUint8 m_saveRestoreSelectionDepth; nsCOMPtr m_db;