support for filters that reply/forward messages, sr=mscott, a=shaver, 11034

git-svn-id: svn://10.0.0.236/trunk@173945 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
bienvenu%nventure.com
2005-06-01 18:17:51 +00:00
parent 93dd89b397
commit ca6bf36403
11 changed files with 328 additions and 131 deletions

View File

@@ -61,6 +61,8 @@ interface nsIMsgRuleAction : nsISupports {
attribute long junkScore;
attribute string strValue;
};
[scriptable, uuid(605db0f8-04a1-11d3-a50a-0060b0fc04b7)]

View File

@@ -54,6 +54,8 @@ var gActionValueDeck;
var gActionPriority;
var gActionLabel;
var gActionJunkScore;
var gActionForwardTo;
var gReplyWithTemplateUri;
var gFilterBundle;
var gPreFillName;
var nsMsgSearchScope = Components.interfaces.nsMsgSearchScope;
@@ -72,6 +74,7 @@ var gWatchCheckbox;
var gDeleteFromServerCheckbox;
var gFetchBodyFromServerCheckbox;
var gFilterActionList;
var gRDF = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService(Components.interfaces.nsIRDFService);
var nsMsgFilterAction = Components.interfaces.nsMsgFilterAction;
@@ -96,11 +99,13 @@ function filterEditorOnLoad()
// editing a filter
gFilter = window.arguments[0].filter;
initializeDialog(gFilter);
PopulateTemplateMenu();
}
else {
if (gFilterList)
setSearchScope(getScopeFromFilterList(gFilterList));
PopulateTemplateMenu();
// if doing prefill filter create a new filter and populate it.
if ("filterName" in args) {
gPreFillName = args.filterName;
@@ -268,10 +273,13 @@ function initializeFilterWidgets()
gActionPriority = document.getElementById("actionValuePriority");
gActionJunkScore = document.getElementById("actionValueJunkScore");
gActionLabel = document.getElementById("actionValueLabel");
gActionForwardTo = document.getElementById("actionValueForward");
gMoveToFolderCheckbox = document.getElementById("moveToFolder");
gCopyToFolderCheckbox = document.getElementById("copyToFolder");
gChangePriorityCheckbox = document.getElementById("changePriority");
gLabelCheckbox = document.getElementById("label");
gForwardToCheckbox = document.getElementById("forwardTo");
gReplyWithTemplateCheckbox = document.getElementById("replyWithTemplate");
gJunkScoreCheckbox = document.getElementById("setJunkScore");
gMarkReadCheckbox = document.getElementById("markRead");
gMarkFlaggedCheckbox = document.getElementById("markFlagged");
@@ -293,7 +301,8 @@ function initializeDialog(filter)
{
var filterAction = actionList.QueryElementAt(actionIndex, Components.interfaces.nsIMsgRuleAction);
if (filterAction.type == nsMsgFilterAction.MoveToFolder) {
if (filterAction.type == nsMsgFilterAction.MoveToFolder)
{
// preselect target folder
gMoveToFolderCheckbox.checked = true;
var target = filterAction.targetFolderUri;
@@ -315,9 +324,7 @@ function initializeDialog(filter)
var selectedPriority = gActionPriority.getElementsByAttribute("value", filterAction.priority).item(0);
if (selectedPriority)
{
gActionPriority.selectedItem = selectedPriority;
}
}
else if (filterAction.type == nsMsgFilterAction.Label)
{
@@ -325,9 +332,7 @@ function initializeDialog(filter)
// initialize label
var selectedLabel = gActionLabel.getElementsByAttribute("value", filterAction.label).item(0);
if (selectedLabel)
{
gActionLabel.selectedItem = selectedLabel;
}
}
else if (filterAction.type == nsMsgFilterAction.JunkScore)
{
@@ -336,9 +341,17 @@ function initializeDialog(filter)
var selectedJunkScore = gActionJunkScore.getElementsByAttribute("value", filterAction.junkScore).item(0);
if (selectedJunkScore)
{
gActionJunkScore.selectedItem = selectedJunkScore;
}
}
else if (filterAction.type == nsMsgFilterAction.Forward)
{
gForwardToCheckbox.checked = true;
gActionForwardTo.value = filterAction.strValue;
}
else if (filterAction.type == nsMsgFilterAction.Reply)
{
gReplyWithTemplateCheckbox.checked = true;
gReplyWithTemplateUri = filterAction.strValue;
}
else if (filterAction.type == nsMsgFilterAction.MarkRead)
gMarkReadCheckbox.checked = true;
@@ -370,9 +383,7 @@ function InitMessageLabel()
/* this code gets the label strings and changes the menu labels */
var lastLabel = 5;
for (var i = 0; i <= lastLabel; i++)
{
setLabelAttributes(i, "labelMenuItem" + i);
}
/* We set the label attribute for labels here because they have to be read from prefs. Default selection
is always 0 and the picker thinks that it is already showing the label but it is not. Just setting selectedIndex
@@ -385,6 +396,40 @@ function InitMessageLabel()
document.commandDispatcher.updateCommands('create-menu-label');
}
function PopulateTemplateMenu()
{
try
{
var accountManager = Components.classes["@mozilla.org/messenger/account-manager;1"].getService(Components.interfaces.nsIMsgAccountManager);
var identity = accountManager.getFirstIdentityForServer(gFilterList.folder.server);
var resource = gRDF.GetResource(identity.stationeryFolder);
var msgFolder = resource.QueryInterface(Components.interfaces.nsIMsgFolder);
var msgWindow = GetFilterEditorMsgWindow();
var msgDatabase = msgFolder.getMsgDatabase(msgWindow);
var enumerator = msgDatabase.EnumerateMessages();
var templateListPopup = document.getElementById('actionValueReplyWithTemplate');
if ( enumerator )
{
while (enumerator.hasMoreElements())
{
var header = enumerator.getNext();
if (header instanceof Components.interfaces.nsIMsgDBHdr)
{
var msgHdr = header.QueryInterface(Components.interfaces.nsIMsgDBHdr);
var msgTemplateUri = msgFolder.URI + "?messageId="+msgHdr.messageId + '&subject=' + msgHdr.subject;
var newItem = templateListPopup.appendItem(msgHdr.subject, msgTemplateUri);
// ### TODO we really want to match based on messageId first, and if we don't get
// any hits, we'll match on subject
if (gReplyWithTemplateUri == msgTemplateUri)
templateListPopup.selectedItem = newItem;
}
}
}
}
catch (ex) {dump(ex);}
}
// move to overlay
function saveFilter()
{
@@ -426,6 +471,8 @@ function saveFilter()
gWatchCheckbox.checked ||
gKillCheckbox.checked ||
gDeleteFromServerCheckbox.checked ||
gForwardToCheckbox.checked ||
gReplyWithTemplateCheckbox.checked ||
gFetchBodyFromServerCheckbox.checked))
{
if (gPromptService)
@@ -447,6 +494,26 @@ function saveFilter()
}
}
if (gForwardToCheckbox.checked &&
(gActionForwardTo.value.length < 3 || gActionForwardTo.value.indexOf('@') < 2))
{
if (gPromptService)
gPromptService.alert(window, null,
gFilterBundle.getString("enterValidEmailAddress"));
return false;
}
if (gReplyWithTemplateCheckbox.checked)
{
var templateListPopup = document.getElementById('actionValueReplyWithTemplate');
if (!templateListPopup.selectedItem)
{
if (gPromptService)
gPromptService.alert(window, null, gFilterBundle.getString("pickTemplateToReplyWith"));
return false;
}
}
if (gCopyToFolderCheckbox.checked)
{
if (gActionTargetCopyElement)
@@ -530,6 +597,23 @@ function saveFilter()
filterAction.junkScore = gActionJunkScore.selectedItem.getAttribute("value");
gFilter.appendAction(filterAction);
}
if (gForwardToCheckbox.checked)
{
filterAction = gFilter.createAction();
filterAction.type = nsMsgFilterAction.Forward;
filterAction.strValue = gActionForwardTo.value;
gFilter.appendAction(filterAction);
}
if (gReplyWithTemplateCheckbox.checked)
{
filterAction = gFilter.createAction();
filterAction.type = nsMsgFilterAction.Reply;
var templateListPopup = document.getElementById('actionValueReplyWithTemplate');
filterAction.strValue = templateListPopup.selectedItem.getAttribute("value");
gFilter.appendAction(filterAction);
}
if (gMarkReadCheckbox.checked)
{

View File

@@ -179,6 +179,27 @@
</listcell>
</listitem>
<listitem allowevents="true">
<listcell>
<checkbox id="forwardTo" label="&forwardTo.label;"/>
</listcell>
<listcell>
<textbox id="actionValueForward" flex="1" />
</listcell>
</listitem>
<listitem allowevents="true">
<listcell>
<checkbox id="replyWithTemplate" label="&replyWithTemplate.label;"/>
</listcell>
<listcell>
<menulist enablefornews="false" id="actionValueReplyWithTemplate" flex="1">
<menupopup id="templateListPopup">
</menupopup>
</menulist>
</listcell>
</listitem>
<listitem allowevents="true">
<listcell>
<checkbox id="markRead" label="&markRead.label;"/>

View File

@@ -29,6 +29,8 @@
<!ENTITY deleteFromServer.label "Delete from POP server">
<!ENTITY fetchBodyFromServer.label "Fetch body from POP server">
<!ENTITY setJunkScore.label "Set Junk Status to:">
<!ENTITY forwardTo.label "Forward to:">
<!ENTITY replyWithTemplate.label "Reply with template:">
<!ENTITY filterName.label "Filter name:">
<!ENTITY filterName.accesskey "i">

View File

@@ -1,4 +1,6 @@
mustSelectFolder=You must select a target folder.
enterValidEmailAddress=Enter a valid e-mail address to forward to.
pickTemplateToReplyWith=Choose a template to reply with.
mustEnterName=You must give this filter a name.
mustSelectAction=You must select at least one filter action.
cannotHaveDuplicateFilterTitle=Duplicate Filter Name

View File

@@ -152,6 +152,21 @@ nsMsgRuleAction::GetJunkScore(PRInt32 *aResult)
return NS_OK;
}
NS_IMETHODIMP
nsMsgRuleAction::SetStrValue(const char *aStrValue)
{
m_strValue = aStrValue;
return NS_OK;
}
NS_IMETHODIMP
nsMsgRuleAction::GetStrValue(char **aStrValue)
{
NS_ENSURE_ARG_POINTER(aStrValue);
*aStrValue = ToNewCString(m_strValue);
return NS_OK;
}
nsMsgFilter::nsMsgFilter():
m_temporary(PR_FALSE),
m_unparseable(PR_FALSE),
@@ -711,6 +726,16 @@ nsresult nsMsgFilter::SaveRule(nsIOFileStream *aStream)
action->GetJunkScore(&junkScore);
err = filterList->WriteIntAttr(nsIMsgFilterList::attribActionValue, junkScore, aStream);
}
break;
case nsMsgFilterAction::Reply:
case nsMsgFilterAction::Forward:
{
nsXPIDLCString strValue;
action->GetStrValue(getter_Copies(strValue));
// strValue is e-mail address
err = filterList->WriteStrAttr(nsIMsgFilterList::attribActionValue, strValue.get(), aStream);
}
break;
default:
break;
}

View File

@@ -62,6 +62,8 @@ private:
nsMsgLabelValue m_label; /* label to set rule to */
nsCString m_folderUri;
PRInt32 m_junkScore; /* junk score (or arbitrary int value?) */
// arbitrary string value. Currently, email address to forward to
nsCString m_strValue;
} ;

View File

@@ -517,7 +517,7 @@ nsresult nsMsgFilterList::LoadValue(nsCString &value, nsIOFileStream *aStream)
nsresult nsMsgFilterList::LoadTextFilters(nsIOFileStream *aStream)
{
nsresult err = NS_OK;
nsresult err = NS_OK;
nsMsgFilterFileAttribValue attrib;
nsCOMPtr<nsIImportService> impSvc;
nsCOMPtr<nsIMsgRuleAction> currentFilterAction;
@@ -527,8 +527,8 @@ nsresult nsMsgFilterList::LoadTextFilters(nsIOFileStream *aStream)
{
nsCAutoString value;
PRInt32 intToStringResult;
char curChar;
char curChar;
curChar = LoadAttrib(attrib, aStream);
if (curChar == (char) -1) //reached eof
break;
@@ -537,28 +537,28 @@ nsresult nsMsgFilterList::LoadTextFilters(nsIOFileStream *aStream)
break;
switch(attrib)
{
case nsIMsgFilterList::attribNone:
m_curFilter->SetUnparseable(PR_TRUE);
break;
case nsIMsgFilterList::attribVersion:
m_fileVersion = value.ToInteger(&intToStringResult, 10);
if (intToStringResult != 0)
{
attrib = nsIMsgFilterList::attribNone;
NS_ASSERTION(PR_FALSE, "error parsing filter file version");
}
if (m_fileVersion == k45Version)
{
impSvc = do_GetService(NS_IMPORTSERVICE_CONTRACTID);
NS_ASSERTION(impSvc, "cannot get importService");
}
break;
case nsIMsgFilterList::attribLogging:
m_loggingEnabled = StrToBool(value);
m_unparsedFilterBuffer.Truncate(); //we are going to buffer each filter as we read them, make sure no garbage is there
m_startWritingToBuffer = PR_TRUE; //filters begin now
break;
case nsIMsgFilterList::attribName: //every filter starts w/ a name
case nsIMsgFilterList::attribNone:
m_curFilter->SetUnparseable(PR_TRUE);
break;
case nsIMsgFilterList::attribVersion:
m_fileVersion = value.ToInteger(&intToStringResult, 10);
if (intToStringResult != 0)
{
attrib = nsIMsgFilterList::attribNone;
NS_ASSERTION(PR_FALSE, "error parsing filter file version");
}
if (m_fileVersion == k45Version)
{
impSvc = do_GetService(NS_IMPORTSERVICE_CONTRACTID);
NS_ASSERTION(impSvc, "cannot get importService");
}
break;
case nsIMsgFilterList::attribLogging:
m_loggingEnabled = StrToBool(value);
m_unparsedFilterBuffer.Truncate(); //we are going to buffer each filter as we read them, make sure no garbage is there
m_startWritingToBuffer = PR_TRUE; //filters begin now
break;
case nsIMsgFilterList::attribName: //every filter starts w/ a name
{
if (m_curFilter)
{
@@ -566,7 +566,7 @@ nsresult nsMsgFilterList::LoadTextFilters(nsIOFileStream *aStream)
nsCAutoString nextFilterPart;
nextFilterPart = Substring(m_unparsedFilterBuffer, nextFilterStartPos, m_unparsedFilterBuffer.Length());
m_unparsedFilterBuffer.Truncate(nextFilterStartPos);
PRBool unparseableFilter;
m_curFilter->GetUnparseable(&unparseableFilter);
if (unparseableFilter)
@@ -576,13 +576,13 @@ nsresult nsMsgFilterList::LoadTextFilters(nsIOFileStream *aStream)
}
m_unparsedFilterBuffer = nextFilterPart;
}
nsMsgFilter *filter = new nsMsgFilter;
if (filter == nsnull)
nsMsgFilter *filter = new nsMsgFilter;
if (filter == nsnull)
{
err = NS_ERROR_OUT_OF_MEMORY;
break;
err = NS_ERROR_OUT_OF_MEMORY;
break;
}
filter->SetFilterList(NS_STATIC_CAST(nsIMsgFilterList*,this));
filter->SetFilterList(NS_STATIC_CAST(nsIMsgFilterList*,this));
if (m_fileVersion == k45Version && impSvc)
{
nsAutoString unicodeStr;
@@ -592,100 +592,102 @@ nsresult nsMsgFilterList::LoadTextFilters(nsIOFileStream *aStream)
else
{
PRUnichar *unicodeString =
nsTextFormatter::smprintf(unicodeFormatter, value.get());
filter->SetFilterName(unicodeString);
nsTextFormatter::smprintf(unicodeFormatter, value.get());
filter->SetFilterName(unicodeString);
nsTextFormatter::smprintf_free(unicodeString);
}
m_curFilter = filter;
m_filters->AppendElement(NS_STATIC_CAST(nsISupports*,filter));
m_curFilter = filter;
m_filters->AppendElement(NS_STATIC_CAST(nsISupports*,filter));
}
break;
case nsIMsgFilterList::attribEnabled:
if (m_curFilter)
m_curFilter->SetEnabled(StrToBool(value));
break;
case nsIMsgFilterList::attribDescription:
if (m_curFilter)
m_curFilter->SetFilterDesc(value.get());
break;
case nsIMsgFilterList::attribType:
if (m_curFilter)
m_curFilter->SetType((nsMsgFilterTypeType) value.ToInteger(&intToStringResult, 10));
break;
case nsIMsgFilterList::attribScriptFile:
if (m_curFilter)
m_curFilter->SetFilterScript(&value);
break;
case nsIMsgFilterList::attribAction:
if (m_curFilter)
{
nsMsgRuleActionType actionType = nsMsgFilter::GetActionForFilingStr(value);
if (actionType == nsMsgFilterAction::None)
m_curFilter->SetUnparseable(PR_TRUE);
else
{
err = m_curFilter->CreateAction(getter_AddRefs(currentFilterAction));
NS_ENSURE_SUCCESS(err, err);
currentFilterAction->SetType(actionType);
m_curFilter->AppendAction(currentFilterAction);
}
}
break;
case nsIMsgFilterList::attribActionValue:
if (m_curFilter && currentFilterAction)
case nsIMsgFilterList::attribEnabled:
if (m_curFilter)
m_curFilter->SetEnabled(StrToBool(value));
break;
case nsIMsgFilterList::attribDescription:
if (m_curFilter)
m_curFilter->SetFilterDesc(value.get());
break;
case nsIMsgFilterList::attribType:
if (m_curFilter)
m_curFilter->SetType((nsMsgFilterTypeType) value.ToInteger(&intToStringResult, 10));
break;
case nsIMsgFilterList::attribScriptFile:
if (m_curFilter)
m_curFilter->SetFilterScript(&value);
break;
case nsIMsgFilterList::attribAction:
if (m_curFilter)
{
nsMsgRuleActionType actionType = nsMsgFilter::GetActionForFilingStr(value);
if (actionType == nsMsgFilterAction::None)
m_curFilter->SetUnparseable(PR_TRUE);
else
{
nsMsgRuleActionType type;
currentFilterAction->GetType(&type);
if (type == nsMsgFilterAction::MoveToFolder ||
type == nsMsgFilterAction::CopyToFolder)
{
err = m_curFilter->ConvertMoveOrCopyToFolderValue(currentFilterAction, value);
}
else if (type == nsMsgFilterAction::ChangePriority)
{
nsMsgPriorityValue outPriority;
nsresult res = NS_MsgGetPriorityFromString(value.get(), &outPriority);
if (NS_SUCCEEDED(res))
currentFilterAction->SetPriority(outPriority);
else
NS_ASSERTION(PR_FALSE, "invalid priority in filter file");
}
else if (type == nsMsgFilterAction::Label)
{
PRInt32 res;
PRInt32 labelInt = value.ToInteger(&res, 10);
if (res == 0)
currentFilterAction->SetLabel((nsMsgLabelValue) labelInt);
}
else if (type == nsMsgFilterAction::JunkScore)
{
PRInt32 res;
PRInt32 junkScore = value.ToInteger(&res, 10);
if (!res)
currentFilterAction->SetJunkScore(junkScore);
}
err = m_curFilter->CreateAction(getter_AddRefs(currentFilterAction));
NS_ENSURE_SUCCESS(err, err);
currentFilterAction->SetType(actionType);
m_curFilter->AppendAction(currentFilterAction);
}
break;
case nsIMsgFilterList::attribCondition:
if (m_curFilter)
{
if ( m_fileVersion == k45Version && impSvc)
{
nsAutoString unicodeStr;
impSvc->SystemStringToUnicode(value.get(), unicodeStr);
char *utf8 = ToNewUTF8String(unicodeStr);
value.Assign(utf8);
nsMemory::Free(utf8);
}
err = ParseCondition(m_curFilter, value.get());
if (err == NS_ERROR_INVALID_ARG)
err = m_curFilter->SetUnparseable(PR_TRUE);
NS_ENSURE_SUCCESS(err, err);
}
break;
}
} while (!aStream->eof());
}
break;
case nsIMsgFilterList::attribActionValue:
if (m_curFilter && currentFilterAction)
{
nsMsgRuleActionType type;
currentFilterAction->GetType(&type);
if (type == nsMsgFilterAction::MoveToFolder ||
type == nsMsgFilterAction::CopyToFolder)
err = m_curFilter->ConvertMoveOrCopyToFolderValue(currentFilterAction, value);
else if (type == nsMsgFilterAction::ChangePriority)
{
nsMsgPriorityValue outPriority;
nsresult res = NS_MsgGetPriorityFromString(value.get(), &outPriority);
if (NS_SUCCEEDED(res))
currentFilterAction->SetPriority(outPriority);
else
NS_ASSERTION(PR_FALSE, "invalid priority in filter file");
}
else if (type == nsMsgFilterAction::Label)
{
PRInt32 res;
PRInt32 labelInt = value.ToInteger(&res, 10);
if (res == 0)
currentFilterAction->SetLabel((nsMsgLabelValue) labelInt);
}
else if (type == nsMsgFilterAction::JunkScore)
{
PRInt32 res;
PRInt32 junkScore = value.ToInteger(&res, 10);
if (!res)
currentFilterAction->SetJunkScore(junkScore);
}
else if (type == nsMsgFilterAction::Forward || type == nsMsgFilterAction::Reply)
{
currentFilterAction->SetStrValue(value.get());
}
}
break;
case nsIMsgFilterList::attribCondition:
if (m_curFilter)
{
if ( m_fileVersion == k45Version && impSvc)
{
nsAutoString unicodeStr;
impSvc->SystemStringToUnicode(value.get(), unicodeStr);
char *utf8 = ToNewUTF8String(unicodeStr);
value.Assign(utf8);
nsMemory::Free(utf8);
}
err = ParseCondition(m_curFilter, value.get());
if (err == NS_ERROR_INVALID_ARG)
err = m_curFilter->SetUnparseable(PR_TRUE);
NS_ENSURE_SUCCESS(err, err);
}
break;
}
} while (!aStream->eof());
if (m_curFilter)
{
PRBool unparseableFilter;
@@ -696,8 +698,8 @@ nsresult nsMsgFilterList::LoadTextFilters(nsIOFileStream *aStream)
m_curFilter->SetEnabled(PR_FALSE); //disable the filter because we don't know how to apply it
}
}
return err;
return err;
}
// parse condition like "(subject, contains, fred) AND (body, isn't, "foo)")"

View File

@@ -65,7 +65,9 @@ REQUIRES = xpcom \
txmgr \
caps \
docshell \
uriloader \
msgimap \
msgcompose \
nkcache \
windowwatcher \
embed_base \

View File

@@ -75,6 +75,16 @@
#include "nsMsgSearchCore.h"
#include "nsMailHeaders.h"
#include "nsIMsgMailSession.h"
#include "nsIMsgComposeParams.h"
#include "nsMsgCompCID.h"
#include "nsIInterfaceRequestor.h"
#include "nsIInterfaceRequestorUtils.h"
#include "nsIDocShell.h"
#include "nsIMsgCompose.h"
#include "nsIDomWindowInternal.h"
#include "nsIPrefBranch.h"
#include "nsIPrefService.h"
#include "nsIMsgComposeService.h"
#include "nsIMsgCopyService.h"
static NS_DEFINE_CID(kCMailDB, NS_MAILDB_CID);
@@ -506,6 +516,7 @@ NS_IMETHODIMP nsParseMailMessageState::Clear()
m_return_path.length = 0;
m_account_key.length = 0;
m_in_reply_to.length = 0;
m_replyTo.length = 0;
m_content_type.length = 0;
m_mdn_original_recipient.length = 0;
m_body_lines = 0;
@@ -892,6 +903,8 @@ int nsParseMailMessageState::ParseHeaders ()
// Disposition-Notification-To
else if (!nsCRT::strncasecmp ("Return-Receipt-To", buf, end - buf))
header = &m_mdn_dnt;
else if (!nsCRT::strncasecmp("ReplyTo", buf, end - buf))
header = &m_replyTo;
break;
case 'S': case 's':
if (!nsCRT::strncasecmp ("Subject", buf, end - buf))
@@ -1113,6 +1126,7 @@ int nsParseMailMessageState::FinalizeHeaders()
struct message_header *subject;
struct message_header *id;
struct message_header *inReplyTo;
struct message_header *replyTo;
struct message_header *references;
struct message_header *date;
struct message_header *statush;
@@ -1162,6 +1176,7 @@ int nsParseMailMessageState::FinalizeHeaders()
priority = (m_priority.length ? &m_priority : 0);
mdn_dnt = (m_mdn_dnt.length ? &m_mdn_dnt : 0);
inReplyTo = (m_in_reply_to.length ? &m_in_reply_to : 0);
replyTo = (m_replyTo.length ? &m_replyTo : 0);
content_type = (m_content_type.length ? &m_content_type : 0);
account_key = (m_account_key.length ? &m_account_key :0);
@@ -1214,6 +1229,10 @@ int nsParseMailMessageState::FinalizeHeaders()
if (priorityFlags != nsMsgPriority::notSet)
m_newMsgHdr->SetPriority(priorityFlags);
// if we have a reply to header, and it's different from the from: header,
// set the "replyTo" attribute on the msg hdr.
if (replyTo && (!sender || replyTo->length != sender->length || strncmp(replyTo->value, sender->value, sender->length)))
m_newMsgHdr->SetStringProperty("replyTo", replyTo->value);
// convert the flag values (0xE000000) to label values (0-5)
if (mozstatus2) // only do this if we have a mozstatus2 header
{
@@ -1714,7 +1733,7 @@ NS_IMETHODIMP nsParseNewMailState::ApplyFilterHit(nsIMsgFilter *filter, nsIMsgWi
m_msgMovedByFilter = NS_SUCCEEDED(err);
// cleanup after mailHdr in source DB because we moved the message.
if (m_msgMovedByFilter)
m_mailDB->RemoveHeaderMdbRow(msgHdr);
m_mailDB->RemoveHeaderMdbRow(msgHdr);
}
if (NS_SUCCEEDED(err))
{
@@ -1789,6 +1808,40 @@ NS_IMETHODIMP nsParseNewMailState::ApplyFilterHit(nsIMsgFilter *filter, nsIMsgWi
m_mailDB->SetStringProperty(msgKey, "junkscoreorigin", /* ### should this be plugin? */"plugin");
break;
}
case nsMsgFilterAction::Forward:
{
nsXPIDLCString forwardTo;
filterAction->GetStrValue(getter_Copies(forwardTo));
nsCOMPtr <nsIMsgIncomingServer> server;
rv = m_rootFolder->GetServer(getter_AddRefs(server));
NS_ENSURE_SUCCESS(rv, rv);
if (!forwardTo.IsEmpty())
{
nsCOMPtr <nsIMsgComposeService> compService = do_GetService (NS_MSGCOMPOSESERVICE_CONTRACTID) ;
if (compService)
{
nsAutoString forwardStr;
forwardStr.AssignWithConversion(forwardTo.get());
rv = compService->ForwardMessage(forwardStr, msgHdr, msgWindow, server);
}
}
}
break;
case nsMsgFilterAction::Reply:
{
nsXPIDLCString replyTemplateUri;
filterAction->GetStrValue(getter_Copies(replyTemplateUri));
nsCOMPtr <nsIMsgIncomingServer> server;
rv = m_rootFolder->GetServer(getter_AddRefs(server));
NS_ENSURE_SUCCESS(rv, rv);
if (!replyTemplateUri.IsEmpty())
{
nsCOMPtr <nsIMsgComposeService> compService = do_GetService (NS_MSGCOMPOSESERVICE_CONTRACTID) ;
if (compService)
rv = compService->ReplyWithTemplate(msgHdr, replyTemplateUri, msgWindow, server);
}
}
case nsMsgFilterAction::DeleteFromPop3Server:
{
PRUint32 flags = 0;

View File

@@ -127,6 +127,7 @@ public:
struct message_header m_mozstatus;
struct message_header m_mozstatus2;
struct message_header m_in_reply_to;
struct message_header m_replyTo;
struct message_header m_content_type;
// Support for having multiple To or Cc header lines in a message
@@ -257,6 +258,7 @@ protected:
nsIMsgWindow *msgWindow);
virtual int MarkFilteredMessageRead(nsIMsgDBHdr *msgHdr);
void LogRuleHit(nsIMsgFilter *filter, nsIMsgDBHdr *msgHdr);
nsCOMPtr <nsIMsgFilterList> m_filterList;
nsCOMPtr <nsIMsgFilterList> m_deferredToServerFilterList;
nsCOMPtr <nsIMsgFolder> m_rootFolder;