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;