diff --git a/mozilla/mailnews/base/search/public/nsIMsgFilter.idl b/mozilla/mailnews/base/search/public/nsIMsgFilter.idl
index da5ab46d385..1e779932996 100644
--- a/mozilla/mailnews/base/search/public/nsIMsgFilter.idl
+++ b/mozilla/mailnews/base/search/public/nsIMsgFilter.idl
@@ -61,6 +61,8 @@ interface nsIMsgRuleAction : nsISupports {
attribute long junkScore;
+ attribute string strValue;
+
};
[scriptable, uuid(605db0f8-04a1-11d3-a50a-0060b0fc04b7)]
diff --git a/mozilla/mailnews/base/search/resources/content/FilterEditor.js b/mozilla/mailnews/base/search/resources/content/FilterEditor.js
index c1da332b2da..3529d68cada 100644
--- a/mozilla/mailnews/base/search/resources/content/FilterEditor.js
+++ b/mozilla/mailnews/base/search/resources/content/FilterEditor.js
@@ -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)
{
diff --git a/mozilla/mailnews/base/search/resources/content/FilterEditor.xul b/mozilla/mailnews/base/search/resources/content/FilterEditor.xul
index 1866fc5e9cb..d0367dfe8a0 100644
--- a/mozilla/mailnews/base/search/resources/content/FilterEditor.xul
+++ b/mozilla/mailnews/base/search/resources/content/FilterEditor.xul
@@ -179,6 +179,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
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 f19dc9ef98c..7de539c87d1 100644
--- a/mozilla/mailnews/base/search/resources/locale/en-US/FilterEditor.dtd
+++ b/mozilla/mailnews/base/search/resources/locale/en-US/FilterEditor.dtd
@@ -29,6 +29,8 @@
+
+
diff --git a/mozilla/mailnews/base/search/resources/locale/en-US/filter.properties b/mozilla/mailnews/base/search/resources/locale/en-US/filter.properties
index 284e2e8a9a9..85c1549fe99 100644
--- a/mozilla/mailnews/base/search/resources/locale/en-US/filter.properties
+++ b/mozilla/mailnews/base/search/resources/locale/en-US/filter.properties
@@ -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
diff --git a/mozilla/mailnews/base/search/src/nsMsgFilter.cpp b/mozilla/mailnews/base/search/src/nsMsgFilter.cpp
index 64c0a889b86..01043f9d92d 100644
--- a/mozilla/mailnews/base/search/src/nsMsgFilter.cpp
+++ b/mozilla/mailnews/base/search/src/nsMsgFilter.cpp
@@ -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;
}
diff --git a/mozilla/mailnews/base/search/src/nsMsgFilter.h b/mozilla/mailnews/base/search/src/nsMsgFilter.h
index 54b68a9c5b9..87417ad28cc 100644
--- a/mozilla/mailnews/base/search/src/nsMsgFilter.h
+++ b/mozilla/mailnews/base/search/src/nsMsgFilter.h
@@ -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;
} ;
diff --git a/mozilla/mailnews/base/search/src/nsMsgFilterList.cpp b/mozilla/mailnews/base/search/src/nsMsgFilterList.cpp
index b19373fc515..982b4b586fd 100644
--- a/mozilla/mailnews/base/search/src/nsMsgFilterList.cpp
+++ b/mozilla/mailnews/base/search/src/nsMsgFilterList.cpp
@@ -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 impSvc;
nsCOMPtr 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)")"
diff --git a/mozilla/mailnews/local/src/Makefile.in b/mozilla/mailnews/local/src/Makefile.in
index 53fb3b7ff10..9403126056a 100644
--- a/mozilla/mailnews/local/src/Makefile.in
+++ b/mozilla/mailnews/local/src/Makefile.in
@@ -65,7 +65,9 @@ REQUIRES = xpcom \
txmgr \
caps \
docshell \
+ uriloader \
msgimap \
+ msgcompose \
nkcache \
windowwatcher \
embed_base \
diff --git a/mozilla/mailnews/local/src/nsParseMailbox.cpp b/mozilla/mailnews/local/src/nsParseMailbox.cpp
index 7bee721df9b..637fd8477dd 100644
--- a/mozilla/mailnews/local/src/nsParseMailbox.cpp
+++ b/mozilla/mailnews/local/src/nsParseMailbox.cpp
@@ -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 server;
+ rv = m_rootFolder->GetServer(getter_AddRefs(server));
+ NS_ENSURE_SUCCESS(rv, rv);
+ if (!forwardTo.IsEmpty())
+ {
+ nsCOMPtr 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 server;
+ rv = m_rootFolder->GetServer(getter_AddRefs(server));
+ NS_ENSURE_SUCCESS(rv, rv);
+ if (!replyTemplateUri.IsEmpty())
+ {
+ nsCOMPtr compService = do_GetService (NS_MSGCOMPOSESERVICE_CONTRACTID) ;
+ if (compService)
+ rv = compService->ReplyWithTemplate(msgHdr, replyTemplateUri, msgWindow, server);
+ }
+ }
+
case nsMsgFilterAction::DeleteFromPop3Server:
{
PRUint32 flags = 0;
diff --git a/mozilla/mailnews/local/src/nsParseMailbox.h b/mozilla/mailnews/local/src/nsParseMailbox.h
index 3c4f8758dca..ddc0a99bcf0 100644
--- a/mozilla/mailnews/local/src/nsParseMailbox.h
+++ b/mozilla/mailnews/local/src/nsParseMailbox.h
@@ -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 m_filterList;
nsCOMPtr m_deferredToServerFilterList;
nsCOMPtr m_rootFolder;