--- a/mail/base/content/SearchDialog.js
+++ b/mail/base/content/SearchDialog.js
@@ -96,18 +96,17 @@ var nsSearchResultsController =
case "open_in_folder_button":
if (GetNumSelectedMessages() != 1)
enabled = false;
break;
case "cmd_delete":
case "cmd_shiftDelete":
case "button_delete":
// this assumes that advanced searches don't cross accounts
- if (GetNumSelectedMessages() <= 0 ||
- isNewsURI(gFolderDisplay.view.dbView.getURIForViewIndex(0)))
+ if (GetNumSelectedMessages() <= 0)
enabled = false;
break;
case "saveas_vf_button":
// need someway to see if there are any search criteria...
return true;
case "cmd_selectAll":
return true;
default:
@@ -614,47 +613,35 @@ function onSearchButton(event)
// threadPane.js will be needing this, too
function GetNumSelectedMessages()
{
return gFolderDisplay.treeSelection.count;
}
function MsgDeleteSelectedMessages(aCommandType)
{
- // we don't delete news messages, we just return in that case
- if (gFolderDisplay.selectedMessageIsNews)
- return;
-
- // if mail messages delete
gFolderDisplay.hintAboutToDeleteMessages();
gFolderDisplay.doCommand(aCommandType);
}
function MoveMessageInSearch(destFolder)
{
// Get the msg folder we're moving messages into.
// If the id (uri) is not set, use file-uri which is set for
// "File Here".
let destUri = destFolder.getAttribute('id');
if (destUri.length == 0)
destUri = destFolder.getAttribute('file-uri');
let destMsgFolder = GetMsgFolderFromUri(destUri).QueryInterface(
Components.interfaces.nsIMsgFolder);
- // we don't move news messages, we copy them
- if (gFolderDisplay.selectedMessageIsNews) {
- gFolderDisplay.doCommandWithFolder(nsMsgViewCommandType.copyMessages,
- destMsgFolder);
- }
- else {
- gFolderDisplay.hintAboutToDeleteMessages();
- gFolderDisplay.doCommandWithFolder(nsMsgViewCommandType.moveMessages,
- destMsgFolder);
- }
+ gFolderDisplay.hintAboutToDeleteMessages();
+ gFolderDisplay.doCommandWithFolder(nsMsgViewCommandType.moveMessages,
+ destMsgFolder);
}
function OpenInFolder()
{
MailUtils.displayMessageInFolderTab(gFolderDisplay.selectedMessage);
}
function saveAsVirtualFolder()
--- a/mail/base/content/mail3PaneWindowCommands.js
+++ b/mail/base/content/mail3PaneWindowCommands.js
@@ -245,16 +245,17 @@ var DefaultController =
case "cmd_downloadFlagged":
case "cmd_downloadSelected":
case "cmd_synchronizeOffline":
return MailOfflineMgr.isOnline();
case "cmd_watchThread":
case "cmd_killThread":
case "cmd_killSubthread":
+ case "cmd_cancel":
return(gFolderDisplay.selectedMessageIsNews);
default:
return false;
}
},
isCommandEnabled: function(command)
@@ -268,16 +269,21 @@ var DefaultController =
case "cmd_delete":
UpdateDeleteCommand();
// fall through
case "button_delete":
UpdateDeleteToolbarButton();
return gFolderDisplay.getCommandStatus(nsMsgViewCommandType.deleteMsg);
case "cmd_shiftDelete":
return gFolderDisplay.getCommandStatus(nsMsgViewCommandType.deleteNoTrash);
+ case "cmd_cancel": {
+ let selectedMessages = gFolderDisplay.selectedMessages;
+ return selectedMessages.length == 1 && selectedMessages[0].folder &&
+ selectedMessages[0].folder.server.type == "nntp";
+ }
case "cmd_deleteFolder":
var folders = gFolderTreeView.getSelectedFolders();
if (folders.length == 1) {
var folder = folders[0];
if (folder.server.type == "nntp")
return false; // Just disable the command for news.
else
return CanDeleteFolder(folder);
@@ -616,16 +622,21 @@ var DefaultController =
// If this is a right-click triggered delete, then do not hint about
// the deletion. Note: The code that swaps the selection back in will
// take care of ensuring that this deletion does not make the saved
// selection incorrect.
if (!gRightMouseButtonSavedSelection)
gFolderDisplay.hintAboutToDeleteMessages();
gFolderDisplay.doCommand(nsMsgViewCommandType.deleteMsg);
break;
+ case "cmd_cancel":
+ let message = gFolderDisplay.selectedMessages[0];
+ message.folder.QueryInterface(Components.interfaces.nsIMsgNewsFolder)
+ .cancelMessage(message, msgWindow);
+ break;
case "cmd_shiftDelete":
MarkSelectedMessagesRead(true);
gFolderDisplay.hintAboutToDeleteMessages();
gFolderDisplay.doCommand(nsMsgViewCommandType.deleteNoTrash);
break;
case "cmd_deleteFolder":
gFolderTreeController.deleteFolder();
break;
--- a/mail/base/content/mailWindowOverlay.js
+++ b/mail/base/content/mailWindowOverlay.js
@@ -349,16 +349,17 @@ function InitMessageMenu()
document.getElementById("replyMainMenu").hidden = isNews;
document.getElementById("replySenderMainMenu").hidden = !isNews;
// We only kill and watch threads for news.
document.getElementById("threadItemsSeparator").hidden = !isNews;
document.getElementById("killThread").hidden = !isNews;
document.getElementById("killSubthread").hidden = !isNews;
document.getElementById("watchThread").hidden = !isNews;
+ document.getElementById("menu_cancel").hidden = !isNews;
// Disable the move and copy menus if there are no messages selected or if
// the message is a dummy - e.g. opening a message in the standalone window.
let messageStoredInternally = selectedMsg && !gMessageDisplay.isDummy;
// Disable the move menu if we can't delete msgs from the folder.
let canMove = messageStoredInternally &&
gFolderDisplay.canDeleteSelectedMessages;
@@ -1011,19 +1012,17 @@ function UpdateDeleteToolbarButton()
GetNumSelectedMessages() == 0)
deleteButtonDeck.selectedIndex = 0;
else
deleteButtonDeck.selectedIndex = SelectedMessagesAreDeleted() ? 1 : 0;
}
function UpdateDeleteCommand()
{
var value = "value";
- if (gFolderDisplay.selectedMessageIsNews)
- value += "News";
- else if (SelectedMessagesAreDeleted())
+ if (SelectedMessagesAreDeleted())
value += "IMAPDeleted";
if (GetNumSelectedMessages() < 2)
value += "Message";
else
value += "Messages";
goSetMenuValue("cmd_delete", value);
goSetAccessKey("cmd_delete", value + "AccessKey");
}
@@ -1221,28 +1220,18 @@ function MsgCopyMessage(aDestFolder)
}
/**
* Moves the selected messages to the destination folder
* @param aDestFolder the destination folder
*/
function MsgMoveMessage(aDestFolder)
{
- // We don't move news messages, we copy them.
- // XXX this check is incorrect in two ways. For saved searches we could have
- // cross folder/newsgroup messages, so this check would do the wrong thing.
- // For global search views, we don't have a msgFolder - however as we don't
- // index newsgroup messages, we can at least temporarily get away with this.
- if (gDBView.msgFolder && isNewsURI(gDBView.msgFolder.URI))
- gDBView.doCommandWithFolder(nsMsgViewCommandType.copyMessages, aDestFolder);
- else
- {
- gFolderDisplay.hintAboutToDeleteMessages();
- gDBView.doCommandWithFolder(nsMsgViewCommandType.moveMessages, aDestFolder);
- }
+ gFolderDisplay.hintAboutToDeleteMessages();
+ gDBView.doCommandWithFolder(nsMsgViewCommandType.moveMessages, aDestFolder);
pref.setCharPref("mail.last_msg_movecopy_target_uri", aDestFolder.URI);
pref.setBoolPref("mail.last_msg_movecopy_was_move", true);
}
/**
* Calls the ComposeMessage function with the desired type, and proper default
* based on the event that fired it.
*
@@ -2198,22 +2187,17 @@ function IsGetNextNMessagesEnabled()
}
function SetUpToolbarButtons(uri)
{
var deleteButton = document.getElementById("button-delete");
if (!deleteButton)
return;
- // Eventually, we might want to set up the toolbar differently for imap,
- // pop, and news. For now, just tweak it based on if it is news or not.
- if (isNewsURI(uri))
- deleteButton.setAttribute('hidden', true);
- else
- deleteButton.removeAttribute('hidden');
+ deleteButton.removeAttribute('hidden');
}
function MsgSynchronizeOffline()
{
window.openDialog("chrome://messenger/content/msgSynchronize.xul", "",
"centerscreen,chrome,modal,titlebar,resizable=yes",
{msgWindow:msgWindow});
}
--- a/mail/base/content/mailWindowOverlay.xul
+++ b/mail/base/content/mailWindowOverlay.xul
@@ -194,24 +194,21 @@
valueFolder="&deleteFolderCmd.label;"
valueFolderAccessKey="&deleteFolderCmd.accesskey;"
valueNewsgroup="&unsubscribeNewsgroupCmd.label;"
valueNewsgroupAccessKey="&unsubscribeNewsgroupCmd.accesskey;"
valueMessage="&deleteMsgCmd.label;"
valueMessageAccessKey="&deleteMsgCmd.accesskey;"
valueIMAPDeletedMessage="&undeleteMsgCmd.label;"
valueIMAPDeletedMessageAccessKey="&undeleteMsgCmd.accesskey;"
- valueNewsMessage="&cancelNewsMsgCmd.label;"
- valueNewsMessageAccessKey="&cancelNewsMsgCmd.accesskey;"
valueMessages="&deleteMsgsCmd.label;"
valueMessagesAccessKey="&deleteMsgsCmd.accesskey;"
valueIMAPDeletedMessages="&undeleteMsgsCmd.label;"
- valueIMAPDeletedMessagesAccessKey="&undeleteMsgsCmd.accesskey;"
- valueNewsMessages="&cancelNewsMsgsCmd.label;"
- valueNewsMessagesAccessKey="&cancelNewsMsgsCmd.accesskey;"/>
+ valueIMAPDeletedMessagesAccessKey="&undeleteMsgsCmd.accesskey;"/>
+ <command id="cmd_cancel" oncommand="goDoCommand('cmd_cancel')"/>
<command id="cmd_selectAll"/>
<command id="cmd_selectThread" oncommand="goDoCommand('cmd_selectThread')"/>
<command id="cmd_selectFlagged" oncommand="goDoCommand('cmd_selectFlagged')"/>
<command id="cmd_properties" oncommand="goDoCommand('cmd_properties')"
valueNewsgroup="&folderPropsNewsgroupCmd.label;"
valueFolder="&folderPropsFolderCmd.label;"
valueGeneric="&folderPropsCmd.label;"/>
<command id="cmd_find" oncommand="goDoCommand('cmd_find')" disabled="true"/>
@@ -1479,16 +1476,19 @@
command="cmd_recalculateJunkScore"/>
</menupopup>
</menu>
<menuseparator id="messageMenuAfterMarkSeparator"/>
<menuitem id="archiveMainMenu" label="&archiveMsgCmd.label;"
accesskey="&archiveMsgCmd.accesskey;"
key="key_archive"
command="cmd_archive"/>
+ <menuitem id="menu_cancel" command="cmd_cancel"
+ label="&cancelNewsMsgCmd.label;"
+ accesskey="&cancelNewsMsgCmd.accesskey;"/>
<menu id="moveMenu"
label="&moveMsgToMenu.label;"
accesskey="&moveMsgToMenu.accesskey;"
oncommand="MsgMoveMessage(event.target._folder)">
<menupopup type="folder" mode="filing" showFileHereLabel="true"
showRecent="true" fileHereLabel="&fileHereMenu.label;"
fileHereAccessKey="&fileHereMenu.accesskey;"
recentLabel="&moveCopyMsgRecentMenu.label;"
--- a/mail/locales/en-US/chrome/messenger/messenger.dtd
+++ b/mail/locales/en-US/chrome/messenger/messenger.dtd
@@ -68,24 +68,20 @@
<!ENTITY printSetupCmd.label "Page Setup…">
<!ENTITY printSetupCmd.accesskey "u">
<!-- Edit Menu -->
<!ENTITY deleteMsgCmd.label "Delete Message">
<!ENTITY deleteMsgCmd.accesskey "D">
<!ENTITY undeleteMsgCmd.label "Undelete Message">
<!ENTITY undeleteMsgCmd.accesskey "d">
-<!ENTITY cancelNewsMsgCmd.label "Cancel Message">
-<!ENTITY cancelNewsMsgCmd.accesskey "M">
<!ENTITY deleteMsgsCmd.label "Delete Selected Messages">
<!ENTITY deleteMsgsCmd.accesskey "D">
<!ENTITY undeleteMsgsCmd.label "Undelete Selected Messages">
<!ENTITY undeleteMsgsCmd.accesskey "d">
-<!ENTITY cancelNewsMsgsCmd.label "Cancel Selected Messages">
-<!ENTITY cancelNewsMsgsCmd.accesskey "n">
<!ENTITY deleteFolderCmd.label "Delete Folder">
<!ENTITY deleteFolderCmd.accesskey "D">
<!ENTITY unsubscribeNewsgroupCmd.label "Unsubscribe">
<!ENTITY unsubscribeNewsgroupCmd.accesskey "n">
<!ENTITY selectMenu.label "Select">
<!ENTITY selectMenu.accesskey "S">
<!ENTITY all.label "All">
<!ENTITY all.accesskey "A">
@@ -325,16 +321,18 @@ you can use these alternative items. Oth
<!ENTITY msgMenu.accesskey "M">
<!ENTITY newMsgCmd.label "New Message">
<!ENTITY newMsgCmd.accesskey "N">
<!ENTITY newNewMsgCmd.label "Message">
<!ENTITY newNewMsgCmd.accesskey "M">
<!ENTITY archiveMsgCmd.label "Archive">
<!ENTITY archiveMsgCmd.accesskey "A">
<!ENTITY archiveMsgCmd.key "a">
+<!ENTITY cancelNewsMsgCmd.label "Cancel Message">
+<!ENTITY cancelNewsMsgCmd.accesskey "C">
<!ENTITY replyMsgCmd.label "Reply">
<!ENTITY replyMsgCmd.accesskey "R">
<!ENTITY replyMsgCmd.key "r">
<!ENTITY replySenderCmd.label "Reply to Sender Only">
<!ENTITY replySenderCmd.accesskey "R">
<!ENTITY replyNewsgroupCmd.label "Reply to Newsgroup">
<!ENTITY replyNewsgroupCmd.accesskey "y">
<!ENTITY replyToAllMsgCmd.label "Reply to All">
--- a/mail/locales/en-US/chrome/messenger/news.properties
+++ b/mail/locales/en-US/chrome/messenger/news.properties
@@ -62,18 +62,16 @@ newNewsgroupHeaders=Downloading %1$S of
# header being filtered on, %2$S is the number of the current header being
# downloaded, %3$S is the number of headers to be downloaded, and %4$S is the
# newsgroup whose headers are being downloaded.
newNewsgroupFilteringHeaders=Getting headers for filters: %1$S (%2$S/%3$S) on %4$S
downloadingArticles=Downloading articles %S-%S
bytesReceived=Downloading newsgroups: %S received (%SKB read at %SKB/sec)
downloadingArticlesForOffline=Downloading articles %S-%S in %S
-onlyCancelOneMessage=You can only cancel one article at a time.
-
# LOCALIZATION NOTE (autoUnsubscribeText): %1$S is the newsgroup and %2$S is the newsgroup-server it is being removed from.
autoUnsubscribeText=The newsgroup %1$S does not appear to exist on the host %2$S. Would you like to unsubscribe from it?
# LOCALIZATION NOTE (autoSubscribeText): %1$S is the newsgroup.
autoSubscribeText=Would you like to subscribe to %1$S?
# LOCALIZATION NOTE (Error -304): In the following item, don't translate "NNTP"
# Error - server error
--- a/mailnews/base/public/nsIMsgFolder.idl
+++ b/mailnews/base/public/nsIMsgFolder.idl
@@ -405,16 +405,26 @@ interface nsIMsgFolder : nsISupports {
*/
boolean isSpecialFolder(in unsigned long flags,
[optional] in boolean checkAncestors);
void getExpansionArray(in nsISupportsArray expansionArray);
ACString getUriForMsg(in nsIMsgDBHdr msgHdr);
+ /**
+ * Deletes the messages from the folder.
+ *
+ * @param messages The array of nsIMsgDBHdr objects to be deleted.
+ * @param msgWindow The standard message window object, for alerts et al.
+ * @param deleteStorage Whether or not the message should be truly deleted, as
+ opposed to moving to trash.
+ * @param isMove Whether or not this is a deletion for moving messages.
+ * @param allowUndo Whether this action should be undoable.
+ */
void deleteMessages(in nsIArray messages,
in nsIMsgWindow msgWindow,
in boolean deleteStorage, in boolean isMove,
in nsIMsgCopyServiceListener listener, in boolean allowUndo);
void copyMessages(in nsIMsgFolder srcFolder, in nsIArray messages,
in boolean isMove, in nsIMsgWindow msgWindow,
in nsIMsgCopyServiceListener listener, in boolean isFolder,
--- a/mailnews/base/src/nsMsgDBView.cpp
+++ b/mailnews/base/src/nsMsgDBView.cpp
@@ -2503,19 +2503,17 @@ NS_IMETHODIMP nsMsgDBView::GetCommandSta
haveSelection = m_currentlyDisplayedViewIndex != nsMsgViewIndex_None;
switch (command)
{
case nsMsgViewCommandType::deleteMsg:
case nsMsgViewCommandType::deleteNoTrash:
{
PRBool canDelete;
- // news folders can't delete (or move messages)
- // but we use delete for cancel messages.
- if (m_folder && !mIsNews && NS_SUCCEEDED(m_folder->GetCanDeleteMessages(&canDelete)) && !canDelete)
+ if (m_folder && NS_SUCCEEDED(m_folder->GetCanDeleteMessages(&canDelete)) && !canDelete)
*selectable_p = PR_FALSE;
else
*selectable_p = haveSelection;
}
break;
case nsMsgViewCommandType::applyFilters:
// disable if no messages
// XXX todo, check that we have filters, and at least one is enabled
--- a/mailnews/news/public/nsIMsgNewsFolder.idl
+++ b/mailnews/news/public/nsIMsgNewsFolder.idl
@@ -42,17 +42,17 @@
#include "nsTArray.h"
%}
interface nsIMsgWindow;
interface nsINntpIncomingServer;
[ref] native nsMsgKeyArrayRef(nsTArray<nsMsgKey>);
-[scriptable, uuid(e56a2366-e66c-4240-a9a1-48c4a0a9ffbc)]
+[scriptable, uuid(86a38356-6ab0-4117-8269-674cbb4f264f)]
interface nsIMsgNewsFolder : nsISupports {
attribute ACString groupUsername;
attribute ACString groupPassword;
readonly attribute AString unicodeName;
/**|rawName| is an 8-bit string to represent the name of a newsgroup used by
* a news server. It's offered for the convenience of callers so that they
* don't have to convert |unicodeName| to the server-side name when
@@ -96,9 +96,20 @@ interface nsIMsgNewsFolder : nsISupports
void notifyFinishedDownloadinghdrs();
/**
* Retrieves the database, but does not cache it in mDatabase.
*
* This is useful for operations that shouldn't hold open the database.
*/
nsIMsgDatabase getDatabaseWithoutCache();
+
+ /**
+ * Requests that a message be canceled.
+ *
+ * Note that, before sending the news cancel, this method will check to make
+ * sure that the user has proper permission to cancel the message.
+ *
+ * @param aMsgHdr The header of the message to be canceled.
+ * @param aMsgWindow The standard message window object, for error dialogs.
+ */
+ void cancelMessage(in nsIMsgDBHdr aMsgHdr, in nsIMsgWindow aMsgWindow);
};
--- a/mailnews/news/src/nsNewsFolder.cpp
+++ b/mailnews/news/src/nsNewsFolder.cpp
@@ -396,24 +396,16 @@ nsMsgNewsFolder::GetCanFileMessages(PRBo
{
NS_ENSURE_ARG_POINTER(aResult);
// you can't file messages into a news server or news group
*aResult = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP
-nsMsgNewsFolder::GetCanDeleteMessages(PRBool *aCanDeleteMessages)
-{
- NS_ENSURE_ARG_POINTER(aCanDeleteMessages);
- *aCanDeleteMessages = PR_FALSE;
- return NS_OK;
-}
-
-NS_IMETHODIMP
nsMsgNewsFolder::GetCanCreateSubfolders(PRBool *aResult)
{
NS_ENSURE_ARG_POINTER(aResult);
*aResult = PR_FALSE;
// you can't create subfolders on a news server or a news group
return NS_OK;
}
@@ -786,62 +778,71 @@ NS_IMETHODIMP nsMsgNewsFolder::GetRequir
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsMsgNewsFolder::GetSizeOnDisk(PRUint32 *size)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
-/* this is news, so remember that DeleteMessage is really CANCEL. */
NS_IMETHODIMP
nsMsgNewsFolder::DeleteMessages(nsIArray *messages, nsIMsgWindow *aMsgWindow,
PRBool deleteStorage, PRBool isMove,
- nsIMsgCopyServiceListener* listener, PRBool allowUndo)
+ nsIMsgCopyServiceListener* listener,
+ PRBool allowUndo)
{
nsresult rv = NS_OK;
NS_ENSURE_ARG_POINTER(messages);
NS_ENSURE_ARG_POINTER(aMsgWindow);
- PRUint32 count = 0;
- rv = messages->GetLength(&count);
+ if (!isMove)
+ {
+ nsCOMPtr<nsIMsgFolderNotificationService> notifier(do_GetService(NS_MSGNOTIFICATIONSERVICE_CONTRACTID));
+ if (notifier)
+ notifier->NotifyMsgsDeleted(messages);
+ }
+
+ rv = GetDatabase();
NS_ENSURE_SUCCESS(rv, rv);
- if (count != 1)
+ rv = EnableNotifications(allMessageCountNotifications, PR_FALSE, PR_TRUE);
+ if (NS_SUCCEEDED(rv))
{
- nsCOMPtr<nsIStringBundleService> bundleService = do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
- NS_ENSURE_SUCCESS(rv, rv);
-
- nsCOMPtr<nsIStringBundle> bundle;
- rv = bundleService->CreateBundle(NEWS_MSGS_URL, getter_AddRefs(bundle));
+ PRUint32 count = 0;
+ rv = messages->GetLength(&count);
NS_ENSURE_SUCCESS(rv, rv);
- nsString alertText;
- rv = bundle->GetStringFromName(NS_LITERAL_STRING("onlyCancelOneMessage").get(), getter_Copies(alertText));
- NS_ENSURE_SUCCESS(rv, rv);
-
- nsCOMPtr<nsIPrompt> dialog;
- rv = aMsgWindow->GetPromptDialog(getter_AddRefs(dialog));
- NS_ENSURE_SUCCESS(rv,rv);
+ for (PRUint32 i = 0; i < count && NS_SUCCEEDED(rv); i++)
+ {
+ nsCOMPtr<nsIMsgDBHdr> msgHdr = do_QueryElementAt(messages, i, &rv);
+ if (msgHdr)
+ rv = mDatabase->DeleteHeader(msgHdr, nsnull, PR_TRUE, PR_TRUE);
+ }
+ EnableNotifications(allMessageCountNotifications, PR_TRUE, PR_TRUE);
+ }
+
+ if (!isMove)
+ NotifyFolderEvent(NS_SUCCEEDED(rv) ? mDeleteOrMoveMsgCompletedAtom :
+ mDeleteOrMoveMsgFailedAtom);
- if (dialog)
- {
- rv = dialog->Alert(nsnull, alertText.get());
- NS_ENSURE_SUCCESS(rv,rv);
- }
- // return failure, since the cancel failed
- return NS_ERROR_FAILURE;
- }
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgNewsFolder::CancelMessage(nsIMsgDBHdr *msgHdr,
+ nsIMsgWindow *aMsgWindow)
+{
+ NS_ENSURE_ARG_POINTER(msgHdr);
+ NS_ENSURE_ARG_POINTER(aMsgWindow);
+
+ nsresult rv;
nsCOMPtr <nsINntpService> nntpService = do_GetService(NS_NNTPSERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv,rv);
- nsCOMPtr<nsIMsgDBHdr> msgHdr(do_QueryElementAt(messages, 0));
-
// for cancel, we need to
// turn "newsmessage://sspitzer@news.mozilla.org/netscape.test#5428"
// into "news://sspitzer@news.mozilla.org/23423@netscape.com"
nsCOMPtr <nsIMsgIncomingServer> server;
rv = GetServer(getter_AddRefs(server));
NS_ENSURE_SUCCESS(rv,rv);
--- a/mailnews/news/src/nsNewsFolder.h
+++ b/mailnews/news/src/nsNewsFolder.h
@@ -89,17 +89,16 @@ public:
NS_IMETHOD DeleteMessages(nsIArray *messages,
nsIMsgWindow *msgWindow, PRBool deleteStorage, PRBool isMove,
nsIMsgCopyServiceListener* listener, PRBool allowUndo);
NS_IMETHOD GetNewMessages(nsIMsgWindow *aWindow, nsIUrlListener *aListener);
NS_IMETHOD GetCanSubscribe(PRBool *aResult);
NS_IMETHOD GetCanFileMessages(PRBool *aResult);
- NS_IMETHOD GetCanDeleteMessages(PRBool *aCanDeleteMessages);
NS_IMETHOD GetCanCreateSubfolders(PRBool *aResult);
NS_IMETHOD GetCanRename(PRBool *aResult);
NS_IMETHOD GetCanCompact(PRBool *aResult);
NS_IMETHOD OnReadChanged(nsIDBChangeListener * aInstigator);
NS_IMETHOD DownloadMessagesForOffline(nsIArray *messages, nsIMsgWindow *window);
NS_IMETHOD Compact(nsIUrlListener *aListener, nsIMsgWindow *aMsgWindow);
NS_IMETHOD DownloadAllForOffline(nsIUrlListener *listener, nsIMsgWindow *msgWindow);
--- a/suite/locales/en-US/chrome/mailnews/messenger.dtd
+++ b/suite/locales/en-US/chrome/mailnews/messenger.dtd
@@ -121,18 +121,16 @@
<!ENTITY undeleteMsgCmd.label "Undelete Message">
<!ENTITY undeleteMsgCmd.accesskey "d">
<!ENTITY cancelNewsMsgCmd.label "Cancel Message">
<!ENTITY cancelNewsMsgCmd.accesskey "n">
<!ENTITY deleteMsgsCmd.label "Delete Selected Messages">
<!ENTITY deleteMsgsCmd.accesskey "D">
<!ENTITY undeleteMsgsCmd.label "Undelete Selected Messages">
<!ENTITY undeleteMsgsCmd.accesskey "d">
-<!ENTITY cancelNewsMsgsCmd.label "Cancel Selected Messages">
-<!ENTITY cancelNewsMsgsCmd.accesskey "n">
<!ENTITY deleteFolderCmd.label "Delete Folder">
<!ENTITY deleteFolderCmd.accesskey "D">
<!ENTITY unsubscribeNewsgroupCmd.label "Unsubscribe">
<!ENTITY unsubscribeNewsgroupCmd.accesskey "n">
<!ENTITY selectMenu.label "Select">
<!ENTITY selectMenu.accesskey "S">
<!ENTITY selectThreadCmd.label "Thread">
<!ENTITY selectThreadCmd.accesskey "T">
--- a/suite/locales/en-US/chrome/mailnews/news.properties
+++ b/suite/locales/en-US/chrome/mailnews/news.properties
@@ -62,18 +62,16 @@ newNewsgroupHeaders=Downloading %1$S of
# header being filtered on, %2$S is the number of the current header being
# downloaded, %3$S is the number of headers to be downloaded, and %4$S is the
# newsgroup whose headers are being downloaded.
newNewsgroupFilteringHeaders=Getting headers for filters: %1$S (%2$S/%3$S) on %4$S
downloadingArticles=Downloading articles %S-%S
bytesReceived=Downloading newsgroups: %S received (%SKB read at %SKB/sec)
downloadingArticlesForOffline=Downloading articles %S-%S in %S
-onlyCancelOneMessage=You can only cancel one article at a time.
-
# LOCALIZATION NOTE (autoUnsubscribeText): %1$S is the newsgroup and %2$S is the newsgroup-server it is being removed from.
autoUnsubscribeText=The newsgroup %1$S does not appear to exist on the host %2$S. Would you like to unsubscribe from it?
# LOCALIZATION NOTE (autoSubscribeText): %1$S is the newsgroup.
autoSubscribeText=Would you like to subscribe to %1$S?
# LOCALIZATION NOTE (Error -304): In the following item, don't translate "NNTP"
# Error - server error
--- a/suite/mailnews/mail3PaneWindowCommands.js
+++ b/suite/mailnews/mail3PaneWindowCommands.js
@@ -241,16 +241,17 @@ var DefaultController =
case "cmd_downloadFlagged":
case "cmd_downloadSelected":
case "cmd_synchronizeOffline":
return(CheckOnline());
case "cmd_watchThread":
case "cmd_killThread":
case "cmd_killSubthread":
+ case "cmd_cancel":
return(isNewsURI(GetFirstSelectedMessage()));
default:
return false;
}
},
isCommandEnabled: function(command)
@@ -270,16 +271,19 @@ var DefaultController =
if (gDBView)
gDBView.getCommandStatus(nsMsgViewCommandType.deleteMsg, enabled, checkStatus);
return enabled.value;
case "cmd_shiftDelete":
case "button_shiftDelete":
if (gDBView)
gDBView.getCommandStatus(nsMsgViewCommandType.deleteNoTrash, enabled, checkStatus);
return enabled.value;
+ case "cmd_cancel":
+ return GetNumSelectedMessages() == 1 &&
+ gFolderDisplay.selectedMessageIsNews;
case "button_junk":
UpdateJunkToolbarButton();
if (gDBView)
gDBView.getCommandStatus(nsMsgViewCommandType.junk, enabled, checkStatus);
return enabled.value;
case "cmd_killThread":
case "cmd_killSubthread":
return GetNumSelectedMessages() > 0;
@@ -552,16 +556,21 @@ var DefaultController =
MsgDeleteMessage(false);
UpdateDeleteToolbarButton(false);
break;
case "cmd_shiftDelete":
case "button_shiftDelete":
MsgDeleteMessage(true);
UpdateDeleteToolbarButton(false);
break;
+ case "cmd_cancel":
+ let message = gFolderDisplay.selectedMessage;
+ message.folder.QueryInterface(Components.interfaces.nsIMsgNewsFolder)
+ .cancelMessage(message, msgWindow);
+ break;
case "cmd_killThread":
/* kill thread kills the thread and then does a next unread */
GoNextMessage(nsMsgNavigationType.toggleThreadKilled, true);
break;
case "cmd_killSubthread":
GoNextMessage(nsMsgNavigationType.toggleSubthreadKilled, true);
break;
case "cmd_watchThread":
--- a/suite/mailnews/mailWindowOverlay.js
+++ b/suite/mailnews/mailWindowOverlay.js
@@ -384,16 +384,20 @@ function InitMessageMenu()
var killSubthreadMenuItem = document.getElementById("killSubthread");
if (killSubthreadMenuItem) {
killSubthreadMenuItem.setAttribute("hidden", isNews ? "" : "true");
}
var watchThreadMenuItem = document.getElementById("watchThread");
if (watchThreadMenuItem) {
watchThreadMenuItem.setAttribute("hidden", isNews ? "" : "true");
}
+ var cancelMenuItem = document.getElementById("menu_cancel");
+ if (cancelMenuItem) {
+ cancelMenuItem.setAttribute("hidden", isNews ? "" : "true");
+ }
// Disable the Move and Copy menus if there are no messages selected.
// Disable the Move menu if we can't delete messages from the folder.
var moveMenu = document.getElementById("moveMenu");
var msgFolder = GetLoadedMsgFolder();
if(moveMenu)
{
var enableMenuItem = aMessage && msgFolder && msgFolder.canDeleteMessages;
@@ -869,19 +873,17 @@ function UpdateDeleteToolbarButton(aFold
// Wallpaper over Bug 491676 by using the attribute instead of the property.
deleteButtonDeck.setAttribute("selectedIndex", selectedIndex);
}
function UpdateDeleteCommand()
{
var value = "value";
var uri = GetFirstSelectedMessage();
- if (IsNewsMessage(uri))
- value += "News";
- else if (SelectedMessagesAreDeleted())
+ if (SelectedMessagesAreDeleted())
value += "IMAPDeleted";
if (GetNumSelectedMessages() < 2)
value += "Message";
else
value += "Messages";
goSetMenuValue("cmd_delete", value);
goSetAccessKey("cmd_delete", value + "AccessKey");
}
@@ -1080,24 +1082,18 @@ function MsgCopyMessage(destFolder)
}
function MsgMoveMessage(destFolder)
{
try {
// get the msg folder we're moving messages into
var destUri = destFolder.getAttribute('id');
let destMsgFolder = GetMsgFolderFromUri(destUri);
- // we don't move news messages, we copy them
- if (isNewsURI(gDBView.msgFolder.URI)) {
- gDBView.doCommandWithFolder(nsMsgViewCommandType.copyMessages, destMsgFolder);
- }
- else {
- SetNextMessageAfterDelete();
- gDBView.doCommandWithFolder(nsMsgViewCommandType.moveMessages, destMsgFolder);
- }
+ SetNextMessageAfterDelete();
+ gDBView.doCommandWithFolder(nsMsgViewCommandType.moveMessages, destMsgFolder);
}
catch (ex) {
dump("MsgMoveMessage failed: " + ex + "\n");
}
}
/**
* Calls the ComposeMessage function with the desired type and proper default
--- a/suite/mailnews/mailWindowOverlay.xul
+++ b/suite/mailnews/mailWindowOverlay.xul
@@ -194,24 +194,20 @@
valueFolder="&deleteFolderCmd.label;"
valueFolderAccessKey="&deleteFolderCmd.accesskey;"
valueNewsgroup="&unsubscribeNewsgroupCmd.label;"
valueNewsgroupAccessKey="&unsubscribeNewsgroupCmd.accesskey;"
valueMessage="&deleteMsgCmd.label;"
valueMessageAccessKey="&deleteMsgCmd.accesskey;"
valueIMAPDeletedMessage="&undeleteMsgCmd.label;"
valueIMAPDeletedMessageAccessKey="&undeleteMsgCmd.accesskey;"
- valueNewsMessage="&cancelNewsMsgCmd.label;"
- valueNewsMessageAccessKey="&cancelNewsMsgCmd.accesskey;"
valueMessages="&deleteMsgsCmd.label;"
valueMessagesAccessKey="&deleteMsgsCmd.accesskey;"
valueIMAPDeletedMessages="&undeleteMsgsCmd.label;"
- valueIMAPDeletedMessagesAccessKey="&undeleteMsgsCmd.accesskey;"
- valueNewsMessages="&cancelNewsMsgsCmd.label;"
- valueNewsMessagesAccessKey="&cancelNewsMsgsCmd.accesskey;"/>
+ valueIMAPDeletedMessagesAccessKey="&undeleteMsgsCmd.accesskey;"/>
<command id="cmd_selectAll"/>
<command id="cmd_selectThread" oncommand="goDoCommand('cmd_selectThread')"/>
<command id="cmd_selectFlagged" oncommand="goDoCommand('cmd_selectFlagged')"/>
<command id="cmd_properties" oncommand="goDoCommand('cmd_properties')"
valueNewsgroup="&folderPropsNewsgroupCmd.label;"
valueFolder="&folderPropsFolderCmd.label;"
valueGeneric="&folderPropsCmd.label;"/>
<command id="cmd_find" oncommand="goDoCommand('cmd_find')" disabled="true"/>
@@ -256,16 +252,17 @@
<command id="cmd_replySenderAndGroup" oncommand="goDoCommand('cmd_replySenderAndGroup')"/>
<command id="cmd_replyAllRecipients" oncommand="goDoCommand('cmd_replyAllRecipients')"/>
<command id="cmd_forward" oncommand="goDoCommand('cmd_forward')"/>
<command id="cmd_forwardInline" oncommand="goDoCommand('cmd_forwardInline')"/>
<command id="cmd_forwardAttachment" oncommand="goDoCommand('cmd_forwardAttachment')"/>
<command id="cmd_editAsNew" oncommand="goDoCommand('cmd_editAsNew')"/>
<command id="cmd_openMessage" oncommand="goDoCommand('cmd_openMessage')"/>
<command id="cmd_createFilterFromMenu" oncommand="goDoCommand('cmd_createFilterFromMenu')"/>
+ <command id="cmd_cancel" oncommand="goDoCommand('cmd_cancel')"/>
<command id="cmd_killThread" oncommand="goDoCommand('cmd_killThread')"/>
<command id="cmd_killSubthread" oncommand="goDoCommand('cmd_killSubthread')"/>
<command id="cmd_watchThread" oncommand="goDoCommand('cmd_watchThread')"/>
</commandset>
<commandset id="mailToolbarItems"
commandupdater="true"
events="mail-toolbar"
@@ -1859,16 +1856,20 @@
</menupopup>
</menu>
<menuseparator id="messageMenuAfterMarkSeparator"/>
<menuitem id="createFilter"
label="&createFilter.label;"
accesskey="&createFilter.accesskey;"
command="cmd_createFilterFromMenu"/>
<menuseparator id="threadItemsSeparator"/>
+ <menuitem id="menu_cancel"
+ label="&cancelNewsMsgCmd.label;"
+ accesskey="&cancelNewsMsgCmd.accesskey;"
+ command="cmd_cancel"/>
<menuitem id="killThread"
label="&killThreadMenu.label;"
accesskey="&killThreadMenu.accesskey;"
key="key_killThread" command="cmd_killThread"/>
<menuitem id="killSubthread"
label="&killSubthreadMenu.label;"
accesskey="&killSubthreadMenu.accesskey;"
key="key_killSubthread" command="cmd_killSubthread"/>
--- a/suite/mailnews/messageWindow.js
+++ b/suite/mailnews/messageWindow.js
@@ -711,17 +711,17 @@ var MessageWindowController =
// fall through
case "button_delete":
if (command == "button_delete")
UpdateDeleteToolbarButton(false);
// fall through
case "cmd_shiftDelete":
case "button_shiftDelete":
loadedFolder = GetLoadedMsgFolder();
- return gCurrentMessageUri && loadedFolder && (loadedFolder.canDeleteMessages || isNewsURI(gCurrentFolderUri));
+ return gCurrentMessageUri && loadedFolder && loadedFolder.canDeleteMessages;
case "button_junk":
UpdateJunkToolbarButton();
// fall through
case "cmd_markAsJunk":
case "cmd_markAsNotJunk":
if (gDBView)
gDBView.getCommandStatus(nsMsgViewCommandType.junk, enabled, checkStatus);
return enabled.value;
--- a/suite/mailnews/search/SearchDialog.js
+++ b/suite/mailnews/search/SearchDialog.js
@@ -94,17 +94,17 @@ var nsSearchResultsController =
case "goto_folder_button":
if (GetNumSelectedMessages() != 1)
enabled = false;
break;
case "cmd_delete":
case "cmd_shiftDelete":
case "button_delete":
// this assumes that advanced searches don't cross accounts
- if (GetNumSelectedMessages() <= 0 || isNewsURI(gSearchView.getURIForViewIndex(0)))
+ if (GetNumSelectedMessages() <= 0)
enabled = false;
break;
case "saveas_vf_button":
// need someway to see if there are any search criteria...
return true;
case "cmd_selectAll":
return GetDBView() != null;
default:
@@ -607,21 +607,16 @@ function GetNumSelectedMessages()
function GetDBView()
{
return gSearchView;
}
function MsgDeleteSelectedMessages(aCommandType)
{
- // we don't delete news messages, we just return in that case
- if (isNewsURI(gSearchView.getURIForViewIndex(0)))
- return;
-
- // if mail messages delete
SetNextMessageAfterDelete();
gSearchView.doCommand(aCommandType);
}
function SetNextMessageAfterDelete()
{
gNextMessageViewIndexAfterDelete = gSearchView.msgToSelectAfterDelete;
}
@@ -736,24 +731,18 @@ function MoveMessageInSearch(destFolder)
// "File Here"
var destUri = destFolder.getAttribute('id');
if (destUri.length == 0) {
destUri = destFolder.getAttribute('file-uri')
}
var destMsgFolder = GetMsgFolderFromUri(destUri).QueryInterface(Components.interfaces.nsIMsgFolder);
- // we don't move news messages, we copy them
- if (isNewsURI(gSearchView.getURIForViewIndex(0))) {
- gSearchView.doCommandWithFolder(nsMsgViewCommandType.copyMessages, destMsgFolder);
- }
- else {
- SetNextMessageAfterDelete();
- gSearchView.doCommandWithFolder(nsMsgViewCommandType.moveMessages, destMsgFolder);
- }
+ SetNextMessageAfterDelete();
+ gSearchView.doCommandWithFolder(nsMsgViewCommandType.moveMessages, destMsgFolder);
}
catch (ex) {
dump("MsgMoveMessage failed: " + ex + "\n");
}
}
function GoToFolder()
{