diff --git a/mozilla/mailnews/base/resources/content/msgFolderPickerOverlay.xul b/mozilla/mailnews/base/resources/content/msgFolderPickerOverlay.xul
index 561653602e9..1b861c83e24 100644
--- a/mozilla/mailnews/base/resources/content/msgFolderPickerOverlay.xul
+++ b/mozilla/mailnews/base/resources/content/msgFolderPickerOverlay.xul
@@ -532,6 +532,70 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ oncommand="MsgNewFolder(function (name,uri){ SearchNewFolderOkCallback(name,uri,'actionTargetFolder'); } )"/>
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/mozilla/mailnews/base/search/resources/locale/en-US/FilterEditor.dtd b/mozilla/mailnews/base/search/resources/locale/en-US/FilterEditor.dtd
index d374226bdcc..f19dc9ef98c 100644
--- a/mozilla/mailnews/base/search/resources/locale/en-US/FilterEditor.dtd
+++ b/mozilla/mailnews/base/search/resources/locale/en-US/FilterEditor.dtd
@@ -17,6 +17,8 @@
+
+
diff --git a/mozilla/mailnews/base/search/src/nsMsgFilter.cpp b/mozilla/mailnews/base/search/src/nsMsgFilter.cpp
index 24e9420e630..64c0a889b86 100644
--- a/mozilla/mailnews/base/search/src/nsMsgFilter.cpp
+++ b/mozilla/mailnews/base/search/src/nsMsgFilter.cpp
@@ -1,4 +1,4 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* -*- Mode: C++; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
@@ -116,7 +116,8 @@ NS_IMETHODIMP
nsMsgRuleAction::SetTargetFolderUri(const char *aUri)
{
NS_ENSURE_ARG_POINTER(aUri);
- NS_ENSURE_TRUE(m_type == nsMsgFilterAction::MoveToFolder,
+ NS_ENSURE_TRUE(m_type == nsMsgFilterAction::MoveToFolder ||
+ m_type == nsMsgFilterAction::CopyToFolder,
NS_ERROR_ILLEGAL_VALUE);
m_folderUri = aUri;
return NS_OK;
@@ -126,7 +127,8 @@ NS_IMETHODIMP
nsMsgRuleAction::GetTargetFolderUri(char** aResult)
{
NS_ENSURE_ARG_POINTER(aResult);
- NS_ENSURE_TRUE(m_type == nsMsgFilterAction::MoveToFolder,
+ NS_ENSURE_TRUE(m_type == nsMsgFilterAction::MoveToFolder ||
+ m_type == nsMsgFilterAction::CopyToFolder,
NS_ERROR_ILLEGAL_VALUE);
*aResult = ToNewCString(m_folderUri);
return NS_OK;
@@ -260,6 +262,7 @@ nsMsgFilter::GetSortedActionList(nsISupportsArray *actionList)
PRUint32 numActions;
nsresult err = m_actionList->Count(&numActions);
NS_ENSURE_SUCCESS(err, err);
+ PRBool insertedFinalAction = PR_FALSE;
PRUint32 front = 0;
for (PRUint32 index =0; index < numActions; index++)
@@ -271,9 +274,32 @@ nsMsgFilter::GetSortedActionList(nsISupportsArray *actionList)
nsMsgRuleActionType actionType;
action->GetType(&actionType);
+
//we always want MoveToFolder action to be last (or delete to trash)
- if (actionType == nsMsgFilterAction::MoveToFolder || actionType == nsMsgFilterAction::Delete)
- actionList->AppendElement(action);
+ if (actionType == nsMsgFilterAction::MoveToFolder || actionType == nsMsgFilterAction::Delete)
+ {
+ err = actionList->AppendElement(action);
+ NS_ENSURE_SUCCESS(err, err);
+ insertedFinalAction = PR_TRUE;
+ }
+ // Copy is always last, except for move/delete
+ else if (actionType == nsMsgFilterAction::CopyToFolder)
+ {
+ if (!insertedFinalAction)
+ {
+ err = actionList->AppendElement(action);
+ NS_ENSURE_SUCCESS(err, err);
+ }
+ else
+ {
+ // If we already have a move/delete action in place, we want to
+ // place ourselves just before that final action.
+ PRUint32 count;
+ actionList->Count(&count);
+ err = actionList->InsertElementAt(action, count - 2);
+ NS_ENSURE_SUCCESS(err, err);
+ }
+ }
else
{
actionList->InsertElementAt(action,front);
@@ -416,14 +442,16 @@ NS_IMETHODIMP nsMsgFilter::LogRuleHit(nsIMsgRuleAction *aFilterAction, nsIMsgDBH
buffer += actionStr;
buffer += " ";
- if (actionType == nsMsgFilterAction::MoveToFolder) {
+ if (actionType == nsMsgFilterAction::MoveToFolder ||
+ actionType == nsMsgFilterAction::CopyToFolder) {
nsXPIDLCString actionFolderUri;
aFilterAction->GetTargetFolderUri(getter_Copies(actionFolderUri));
buffer += actionFolderUri.get();
}
buffer += "\n";
- if (actionType == nsMsgFilterAction::MoveToFolder) {
+ if (actionType == nsMsgFilterAction::MoveToFolder ||
+ actionType == nsMsgFilterAction::CopyToFolder) {
nsXPIDLCString msgId;
aMsgHdr->GetMessageId(getter_Copies(msgId));
buffer += " id = ";
@@ -492,7 +520,7 @@ void nsMsgFilter::SetFilterScript(nsCString *fileName)
m_scriptFileName = *fileName;
}
-nsresult nsMsgFilter::ConvertMoveToFolderValue(nsIMsgRuleAction *filterAction, nsCString &moveValue)
+nsresult nsMsgFilter::ConvertMoveOrCopyToFolderValue(nsIMsgRuleAction *filterAction, nsCString &moveValue)
{
NS_ENSURE_ARG_POINTER(filterAction);
PRInt16 filterVersion = kFileVersion;
@@ -652,6 +680,7 @@ nsresult nsMsgFilter::SaveRule(nsIOFileStream *aStream)
switch(actionType)
{
case nsMsgFilterAction::MoveToFolder:
+ case nsMsgFilterAction::CopyToFolder:
{
nsXPIDLCString imapTargetString;
action->GetTargetFolderUri(getter_Copies(imapTargetString));
@@ -739,6 +768,7 @@ struct RuleActionsTableEntry
static struct RuleActionsTableEntry ruleActionsTable[] =
{
{ nsMsgFilterAction::MoveToFolder, nsMsgFilterType::Inbox, 0, "Move to folder"},
+ { nsMsgFilterAction::CopyToFolder, nsMsgFilterType::Inbox, 0, "Copy to folder"},
{ nsMsgFilterAction::ChangePriority, nsMsgFilterType::Inbox, 0, "Change priority"},
{ nsMsgFilterAction::Delete, nsMsgFilterType::All, 0, "Delete"},
{ nsMsgFilterAction::MarkRead, nsMsgFilterType::All, 0, "Mark read"},
diff --git a/mozilla/mailnews/base/search/src/nsMsgFilter.h b/mozilla/mailnews/base/search/src/nsMsgFilter.h
index 92af8a1c2ac..54b68a9c5b9 100644
--- a/mozilla/mailnews/base/search/src/nsMsgFilter.h
+++ b/mozilla/mailnews/base/search/src/nsMsgFilter.h
@@ -97,7 +97,7 @@ public:
void Dump();
#endif
- nsresult ConvertMoveToFolderValue(nsIMsgRuleAction *filterAction, nsCString &relativePath);
+ nsresult ConvertMoveOrCopyToFolderValue(nsIMsgRuleAction *filterAction, nsCString &relativePath);
static const char *GetActionStr(nsMsgRuleActionType action);
static nsresult GetActionFilingStr(nsMsgRuleActionType action, nsCString &actionStr);
static nsMsgRuleActionType GetActionForFilingStr(nsCString &actionStr);
diff --git a/mozilla/mailnews/base/search/src/nsMsgFilterList.cpp b/mozilla/mailnews/base/search/src/nsMsgFilterList.cpp
index 30b0d3be809..b19373fc515 100644
--- a/mozilla/mailnews/base/search/src/nsMsgFilterList.cpp
+++ b/mozilla/mailnews/base/search/src/nsMsgFilterList.cpp
@@ -636,8 +636,11 @@ nsresult nsMsgFilterList::LoadTextFilters(nsIOFileStream *aStream)
{
nsMsgRuleActionType type;
currentFilterAction->GetType(&type);
- if (type == nsMsgFilterAction::MoveToFolder)
- err = m_curFilter->ConvertMoveToFolderValue(currentFilterAction, value);
+ if (type == nsMsgFilterAction::MoveToFolder ||
+ type == nsMsgFilterAction::CopyToFolder)
+ {
+ err = m_curFilter->ConvertMoveOrCopyToFolderValue(currentFilterAction, value);
+ }
else if (type == nsMsgFilterAction::ChangePriority)
{
nsMsgPriorityValue outPriority;
@@ -1048,7 +1051,8 @@ NS_IMETHODIMP nsMsgFilterList::MatchOrChangeFilterTarget(const char *oldFolderUr
else
continue;
- if (actionType == nsMsgFilterAction::MoveToFolder)
+ if (actionType == nsMsgFilterAction::MoveToFolder ||
+ actionType == nsMsgFilterAction::CopyToFolder)
{
rv = filterAction->GetTargetFolderUri(getter_Copies(folderUri));
if (NS_SUCCEEDED(rv) && folderUri)
diff --git a/mozilla/mailnews/base/search/src/nsMsgFilterService.cpp b/mozilla/mailnews/base/search/src/nsMsgFilterService.cpp
index 91f41e797cf..e3489414265 100644
--- a/mozilla/mailnews/base/search/src/nsMsgFilterService.cpp
+++ b/mozilla/mailnews/base/search/src/nsMsgFilterService.cpp
@@ -508,7 +508,8 @@ nsresult nsMsgFilterAfterTheFact::ApplyFilter()
continue;
nsXPIDLCString actionTargetFolderUri;
- if (actionType == nsMsgFilterAction::MoveToFolder)
+ if (actionType == nsMsgFilterAction::MoveToFolder ||
+ actionType == nsMsgFilterAction::CopyToFolder)
{
filterAction->GetTargetFolderUri(getter_Copies(actionTargetFolderUri));
if (actionTargetFolderUri.IsEmpty())
@@ -544,8 +545,9 @@ nsresult nsMsgFilterAfterTheFact::ApplyFilter()
applyMoreActions = PR_FALSE;
break;
case nsMsgFilterAction::MoveToFolder:
+ case nsMsgFilterAction::CopyToFolder:
{
- // if moving to a different file, do it.
+ // if moving or copying to a different file, do it.
nsXPIDLCString uri;
rv = m_curFolder->GetURI(getter_Copies(uri));
@@ -582,10 +584,11 @@ nsresult nsMsgFilterAfterTheFact::ApplyFilter()
}
nsCOMPtr copyService = do_GetService(NS_MSGCOPYSERVICE_CONTRACTID, &rv);
if (copyService)
- return copyService->CopyMessages(m_curFolder, m_searchHitHdrs, destIFolder, PR_TRUE, this, m_msgWindow, PR_FALSE);
+ return copyService->CopyMessages(m_curFolder, m_searchHitHdrs, destIFolder, actionType == nsMsgFilterAction::MoveToFolder, this, m_msgWindow, PR_FALSE);
}
//we have already moved the hdrs so we can't apply more actions
- applyMoreActions = PR_FALSE;
+ if (actionType == nsMsgFilterAction::MoveToFolder)
+ applyMoreActions = PR_FALSE;
}
break;
diff --git a/mozilla/mailnews/imap/src/nsImapMailFolder.cpp b/mozilla/mailnews/imap/src/nsImapMailFolder.cpp
index cb363376578..2fe63989a3d 100644
--- a/mozilla/mailnews/imap/src/nsImapMailFolder.cpp
+++ b/mozilla/mailnews/imap/src/nsImapMailFolder.cpp
@@ -3204,7 +3204,8 @@ NS_IMETHODIMP nsImapMailFolder::ApplyFilterHit(nsIMsgFilter *filter, nsIMsgWindo
continue;
if (NS_SUCCEEDED(filterAction->GetType(&actionType)))
{
- if (actionType == nsMsgFilterAction::MoveToFolder)
+ if (actionType == nsMsgFilterAction::MoveToFolder ||
+ actionType == nsMsgFilterAction::CopyToFolder)
{
filterAction->GetTargetFolderUri(getter_Copies(actionTargetFolderUri));
if (actionTargetFolderUri.IsEmpty())
@@ -3272,6 +3273,42 @@ NS_IMETHODIMP nsImapMailFolder::ApplyFilterHit(nsIMsgFilter *filter, nsIMsgWindo
*applyMore = PR_FALSE;
}
break;
+ case nsMsgFilterAction::CopyToFolder:
+ {
+ nsXPIDLCString uri;
+ rv = GetURI(getter_Copies(uri));
+
+ if (NS_STATIC_CAST(const char *, actionTargetFolderUri) &&
+ strcmp(uri, actionTargetFolderUri))
+ {
+ // XXXshaver I'm not actually 100% what the right semantics are for
+ // MDNs and copied messages, but I suspect deep down inside that
+ // we probably want to suppress them only on the copies.
+ msgHdr->GetFlags(&msgFlags);
+ if (msgFlags & MSG_FLAG_MDN_REPORT_NEEDED && !isRead)
+ {
+ msgHdr->SetFlags(msgFlags & ~MSG_FLAG_MDN_REPORT_NEEDED);
+ msgHdr->OrFlags(MSG_FLAG_MDN_REPORT_SENT, &newFlags);
+ }
+
+ nsCOMPtr messageArray;
+ NS_NewISupportsArray(getter_AddRefs(messageArray));
+ messageArray->AppendElement(msgHdr);
+
+ nsCOMPtr dstFolder;
+ rv = GetExistingFolder(actionTargetFolderUri,
+ getter_AddRefs(dstFolder));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr copyService =
+ do_GetService(NS_MSGCOPYSERVICE_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = copyService->CopyMessages(this, messageArray, dstFolder,
+ PR_FALSE, nsnull, msgWindow, PR_FALSE);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+ }
+ break;
case nsMsgFilterAction::MarkRead:
{
nsMsgKeyArray keysToFlag;
diff --git a/mozilla/mailnews/local/src/nsParseMailbox.cpp b/mozilla/mailnews/local/src/nsParseMailbox.cpp
index 452506624ed..7bee721df9b 100644
--- a/mozilla/mailnews/local/src/nsParseMailbox.cpp
+++ b/mozilla/mailnews/local/src/nsParseMailbox.cpp
@@ -75,6 +75,7 @@
#include "nsMsgSearchCore.h"
#include "nsMailHeaders.h"
#include "nsIMsgMailSession.h"
+#include "nsIMsgCopyService.h"
static NS_DEFINE_CID(kCMailDB, NS_MAILDB_CID);
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
@@ -1655,7 +1656,8 @@ NS_IMETHODIMP nsParseNewMailState::ApplyFilterHit(nsIMsgFilter *filter, nsIMsgWi
if (NS_SUCCEEDED(filterAction->GetType(&actionType)))
{
- if (actionType == nsMsgFilterAction::MoveToFolder)
+ if (actionType == nsMsgFilterAction::MoveToFolder ||
+ actionType == nsMsgFilterAction::CopyToFolder)
{
filterAction->GetTargetFolderUri(getter_Copies(actionTargetFolderUri));
if (actionTargetFolderUri.IsEmpty())
@@ -1722,6 +1724,33 @@ NS_IMETHODIMP nsParseNewMailState::ApplyFilterHit(nsIMsgFilter *filter, nsIMsgWi
}
*applyMore = PR_FALSE;
break;
+ case nsMsgFilterAction::CopyToFolder:
+ {
+ nsXPIDLCString uri;
+ rv = m_rootFolder->GetURI(getter_Copies(uri));
+
+ if (NS_STATIC_CAST(const char*, actionTargetFolderUri) &&
+ strcmp(uri, actionTargetFolderUri))
+ {
+
+ nsCOMPtr messageArray;
+ NS_NewISupportsArray(getter_AddRefs(messageArray));
+ messageArray->AppendElement(msgHdr);
+
+ nsCOMPtr dstFolder;
+ rv = GetExistingFolder(actionTargetFolderUri,
+ getter_AddRefs(dstFolder));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr copyService =
+ do_GetService(NS_MSGCOPYSERVICE_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = copyService->CopyMessages(m_rootFolder, messageArray, dstFolder,
+ PR_FALSE, nsnull, msgWindow, PR_FALSE);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+ }
+ break;
case nsMsgFilterAction::MarkRead:
msgIsNew = PR_FALSE;
MarkFilteredMessageRead(msgHdr);
@@ -1815,7 +1844,7 @@ NS_IMETHODIMP nsParseNewMailState::ApplyFilterHit(nsIMsgFilter *filter, nsIMsgWi
default:
break;
}
- if (loggingEnabled && actionType != nsMsgFilterAction::MoveToFolder && actionType != nsMsgFilterAction::Delete)
+ if (loggingEnabled && actionType != nsMsgFilterAction::MoveToFolder && actionType != nsMsgFilterAction::Delete)
(void)filter->LogRuleHit(filterAction, msgHdr);
}
}