16902 r=sspitzer sr=bienvenu, Implement custom headers for mail filter and search.

This commit is contained in:
naving%netscape.com 2001-10-10 19:27:06 +00:00
parent bfdc49509c
commit 5b64bf539e
33 changed files with 662 additions and 378 deletions

View File

@ -102,9 +102,28 @@
<![CDATA[
var strings = new Array;
var ids = this.valueIds;
var pref = Components.classes["@mozilla.org/preferences;1"].getService(Components.interfaces.nsIPref);
var hdrs;
try
{
hdrs = pref.GetCharPref("mailnews.customHeaders");
}
catch(ex)
{
hdrs=null;
}
var hdrsArray = new Array;
if (hdrs)
hdrsArray = hdrs.split(": ");
var bundle = this.stringBundle;
var j=0;
for (var i=0; i<ids.length; i++)
{
if(ids[i] > Components.interfaces.nsMsgSearchAttrib.OtherHeader && hdrs)
strings[i] = hdrsArray[j++];
else
strings[i] = this.stringBundle.GetStringFromID(ids[i]);
}
return strings;
]]>
</getter>
@ -150,6 +169,9 @@
]]>
</setter>
</property>
<!-- label forwards to the internal menulist's "label" attribute -->
<property name="label" onget="return document.getAnonymousNodes(this)[0].selectedItem.getAttribute('label');">
</property>
<method name="refreshList">
<body>
<![CDATA[
@ -167,21 +189,35 @@
popup.removeChild(popup.lastChild);
var newSelection;
for (var i=0; i<menuItemIds.length; i++) {
var customizePos=-1;
for (var i=0; i<menuItemIds.length; i++)
{
// create the menuitem
var menuitem = document.createElement("menuitem");
menuitem.setAttribute("label", menuItemStrings[i]);
menuitem.setAttribute("value", menuItemIds[i]);
popup.appendChild(menuitem);
// try to restore the selection
if (!newSelection || oldData == menuItemIds[i].toString()) {
newSelection = menuitem;
if (Components.interfaces.nsMsgSearchAttrib.OtherHeader == menuItemIds[i].toString())
customizePos = i;
else
{
var menuitem = document.createElement("menuitem");
menuitem.setAttribute("label", menuItemStrings[i]);
menuitem.setAttribute("value", menuItemIds[i]);
popup.appendChild(menuitem);
// try to restore the selection
if (!newSelection || oldData == menuItemIds[i].toString())
newSelection = menuitem;
}
}
if (customizePos != -1)
{
var separator = document.createElement("menuseparator");
popup.appendChild(separator);
var menuitem = document.createElement("menuitem");
menuitem.setAttribute("label", menuItemStrings[customizePos]);
menuitem.setAttribute("value", menuItemIds[customizePos]);
popup.appendChild(menuitem);
}
// now restore the selection
menulist.selectedItem = newSelection;
]]>
</body>
</method>
@ -190,7 +226,6 @@
<body>
<![CDATA[
var menulist = document.getAnonymousNodes(this)[0];
// notify targets
var targets = this.targets;
if (targets) {
@ -250,9 +285,14 @@
<property name="parentValue">
<setter>
<![CDATA[
if (this.searchAttribute == val) return val;
if (this.searchAttribute == val && val != Components.interfaces.nsMsgSearchAttrib.OtherHeader) return val;
this.searchAttribute = val;
this.refreshList();
if (val == Components.interfaces.nsMsgSearchAttrib.OtherHeader)
{
window.openDialog('chrome://messenger/content/CustomHeaders.xul', "", 'modal,titlebar,chrome', null);
UpdateAfterCustomHeaderChange();
}
return val;
]]>
</setter>
@ -540,6 +580,8 @@
<![CDATA[
var searchTerm = this.searchTerm;
searchTerm.attrib = this.searchattribute.value;
if (this.searchAttribute > nsMsgSearchAttrib.OtherHeader && this.searchAttribute < nsMsgSearchAttrib.kNumMsgSearchAttributes)
searchTerm.arbitraryHeader = this.searchattribute.label;
searchTerm.op = this.searchoperator.value;
if (this.searchvalue.value)
this.searchvalue.save();

View File

@ -68,7 +68,8 @@ interface nsIMsgFilterList : nsISupports {
attribute nsIMsgFolder folder;
readonly attribute short version;
readonly attribute string arbitraryHeaders;
readonly attribute boolean shouldDownloadArbitraryHeaders;
readonly attribute unsigned long filterCount;
nsIMsgFilter getFilterAt(in unsigned long filterIndex);
nsIMsgFilter getFilterNamed(in wstring filterName);

View File

@ -52,8 +52,8 @@ protected:
void OpenLocalFolder();
// goes through the mail folder
PRInt32 GetNextLocalLine(char * buf, int bufSize);
PRInt32 GetNextLocalLine(char * buf, int bufSize);
nsIMsgSearchScopeTerm *m_scope;
nsCOMPtr <nsIFileSpec> m_fileSpec;
// local file state
@ -70,9 +70,6 @@ protected:
nsIMsgDBHdr * m_msgHdr;
nsIMsgDatabase * m_db;
// News related methods & state
PRInt32 m_NewsArticleOffset;
// Transformations
PRBool m_stripHeaders; // PR_TRUE if we're supposed to strip of message headers
PRBool m_stripHtml; // PR_TRUE if we're supposed to strip off HTML tags

View File

@ -213,6 +213,7 @@ protected:
nsresult InitNewsTable ();
nsresult InitLocalNewsTable();
nsresult InitNewsExTable (nsINntpIncomingServer *host = nsnull);
nsresult InitOtherHeadersInTable(nsIMsgSearchValidityTable *table, const char *customHeaders);
void EnableLdapAttribute (nsMsgSearchAttribValue, PRBool enabled = PR_TRUE);
};

View File

@ -123,9 +123,10 @@ interface nsMsgSearchAttrib {
const long HomePhone = 46;
const long Pager = 47;
const long Cellular = 48;
//49 is for showing customize... in ui headers start from 50 onwards up until 99.
const long OtherHeader = 49; /* for mail and news. MUST ALWAYS BE LAST attribute since we can have an arbitrary # of these... */
const long OtherHeader = 49; /* for mail and news. MUST ALWAYS BE LAST attribute since we can have an arbitrary # of these...*/
const long kNumMsgSearchAttributes = 50; /* must be last attribute */
const long kNumMsgSearchAttributes = 100; /* must be last attribute */
};
/* NB: If you add elements to this enum, add only to the end, since
@ -158,7 +159,6 @@ interface nsMsgSearchOp {
const long IsLessThan = 14;
const long NameCompletion = 15; /* Name Completion operator...as the name implies =) */
const long kNumMsgSearchOperators = 16; /* must be last operator */
};

View File

@ -0,0 +1,155 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998-1999 Netscape Communications Corporation. All
* Rights Reserved.
* Original Contributor(s): Navin Gupta <naving@netscape.com>
*/
var gPrefs;
var addButton;
var removeButton;
var gHeaderInputElement;
var gArrayHdrs;
var gHdrsList;
var gTree;
var gContainer;
function onLoad()
{
gPrefs = Components.classes["@mozilla.org/preferences;1"].getService(Components.interfaces.nsIPref);
var hdrs;
try
{
hdrs = gPrefs.GetCharPref("mailnews.customHeaders");
}
catch(ex)
{
hdrs =null;
}
gHeaderInputElement = document.getElementById("headerInput");
gHdrsList = document.getElementById("headerList");
gTree = document.getElementById("headerTree");
gArrayHdrs = new Array();
addButton = document.getElementById("addButton");
removeButton = document.getElementById("removeButton");
initializeDialog(hdrs);
doSetOKCancel(onOk, null);
updateButtons();
moveToAlertPosition();
}
function initializeDialog(hdrs)
{
if (hdrs)
{
gArrayHdrs = hdrs.split(": ");
initializeRows();
}
}
function initializeRows()
{
for (var i = 0; i< gArrayHdrs.length; i++)
addRow(TrimString(gArrayHdrs[i]));
}
function onOk()
{
if (gArrayHdrs.length)
{
var hdrs = gArrayHdrs.join(": ");
gPrefs.SetCharPref("mailnews.customHeaders", hdrs);
}
window.close();
}
function onAddHeader()
{
var newHdr = TrimString(gHeaderInputElement.value);
gHeaderInputElement.value = "";
if (!newHdr) return;
if (!duplicateHdrExists(newHdr))
{
gArrayHdrs[gArrayHdrs.length] = newHdr;
addRow(newHdr);
}
}
function duplicateHdrExists(hdr)
{
for (var i=0;i<gArrayHdrs.length; i++)
{
if (gArrayHdrs[i] == hdr)
return true;
}
return false;
}
function onRemoveHeader()
{
var treeItem = gTree.selectedItems[0]
if (!treeItem) return;
gHdrsList.removeChild(treeItem);
var selectedHdr = GetTreeItemAttributeStr(treeItem);
var j=0;
for (var i=0;i<gArrayHdrs.length; i++)
{
if (gArrayHdrs[i] == selectedHdr)
{
gArrayHdrs.splice(i,1);
break;
}
}
}
function GetTreeItemAttributeStr(treeItem)
{
if (treeItem)
return TrimString(treeItem.firstChild.firstChild.getAttribute("label"));
return "";
}
function addRow(newHdr)
{
var treeitem = document.createElement("treeitem");
var row = document.createElement("treerow");
var treecell = document.createElement("treecell");
treecell.setAttribute("flex", "1");
treecell.setAttribute("label", newHdr);
row.appendChild(treecell);
treeitem.appendChild(row);
gHdrsList.appendChild(treeitem);
}
function updateButtons()
{
var headerSelected = (gTree.selectedItems.length > 0);
removeButton.disabled = !headerSelected;
}
//Remove whitespace from both ends of a string
function TrimString(string)
{
if (!string) return "";
return string.replace(/(^\s+)|(\s+$)/g, '')
}

View File

@ -0,0 +1,75 @@
<?xml version="1.0"?>
<!--
The contents of this file are subject to the Netscape Public
License Version 1.1 (the "License"); you may not use this file
except in compliance with the License. You may obtain a copy of
the License at http://www.mozilla.org/NPL/
Software distributed under the License is distributed on an "AS
IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
implied. See the License for the specific language governing
rights and limitations under the License.
The Original Code is Mozilla Communicator client code, released
March 31, 1998.
The Initial Developer of the Original Code is Netscape
Communications Corporation. Portions created by Netscape are
Copyright (C) 1998-1999 Netscape Communications Corporation. All
Rights Reserved.
Original Contributor(s): Navin Gupta <naving@netscape.com>
-->
<?xml-stylesheet href="chrome://communicator/skin/" type="text/css"?>
<?xul-overlay href="chrome://global/content/dialogOverlay.xul"?>
<!DOCTYPE window SYSTEM "chrome://messenger/locale/CustomHeaders.dtd">
<window class="dialog" id="customHeaders"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
orient="vertical"
windowtype="mailnews:customheaders"
onload="onLoad();"
width="300"
height="250"
persist="width height screenX screenY"
title="&window.title;">
<script type="application/x-javascript" src="chrome://messenger/content/CustomHeaders.js"/>
<script src="chrome://messenger/content/searchTermOverlay.js"/>
<keyset id="dialogKeys"/>
<grid flex="1">
<columns>
<column flex="1"/>
<column/>
</columns>
<rows>
<row>
<html>&newMsgHeader.label;</html>
</row>
<row>
<textbox flex="50%" id="headerInput"/>
</row>
<row flex="1">
<vbox>
<tree id="headerTree" class="inset" flex="1" onclick="updateButtons();">
<treechildren id="headerList" flex="1"/>
</tree>
</vbox>
<vbox>
<button id="addButton" label="&addButton.label;" oncommand="onAddHeader();"/>
<button id="removeButton" label="&removeButton.label;" oncommand="onRemoveHeader();"/>
</vbox>
</row>
</rows>
</grid>
<separator/>
<hbox id="okCancelButtonsRight"/>
</window>

View File

@ -300,3 +300,8 @@ function SearchNewFolderOkCallback(name,uri)
var curFolder = uri+"/"+name;
SetFolderPicker(curFolder, gActionTargetElement.id);
}
function UpdateAfterCustomHeaderChange()
{
updateSearchAttributes();
}

View File

@ -310,9 +310,12 @@ function updateSearchFolderPicker(folderURI) {
gCurrentFolder =
RDF.GetResource(folderURI).QueryInterface(nsIMsgFolder);
setSearchScope(GetScopeForFolder(gCurrentFolder));
}
function UpdateAfterCustomHeaderChange()
{
updateSearchAttributes();
}
function onChooseFolder(event) {

View File

@ -143,6 +143,9 @@ searchTermContainer.prototype = {
save: function () {
var searchTerm = this.searchTerm;
searchTerm.attrib = this.searchattribute.value;
var nsMsgSearchAttrib = Components.interfaces.nsMsgSearchAttrib;
if (this.searchattribute.value > nsMsgSearchAttrib.OtherHeader && this.searchattribute.value < nsMsgSearchAttrib.kNumMsgSearchAttributes)
searchTerm.arbitraryHeader = this.searchattribute.label;
searchTerm.op = this.searchoperator.value;
if (this.searchvalue.value)
this.searchvalue.save();
@ -231,6 +234,13 @@ function setSearchScope(scope) {
}
}
function updateSearchAttributes()
{
for (var i=0; i<gSearchTerms.length; i++) {
gSearchTerms[i].obj.searchattribute.refreshList();
}
}
function booleanChanged(event) {
// when boolean changes, we have to update all the attributes on the
// search terms
@ -465,3 +475,4 @@ function convertStringToPRTime(str)
// so multiply by 1000 when converting
return (time.getTime() * 1000);
}

View File

@ -0,0 +1,4 @@
<!ENTITY window.title "Customize Headers">
<!ENTITY addButton.label "Add">
<!ENTITY removeButton.label "Remove">
<!ENTITY newMsgHeader.label "New message header:">

View File

@ -34,3 +34,4 @@
<!ENTITY filterActionDesc.label "Perform this action:">
<!ENTITY newFolderButton.label "New folder...">

View File

@ -54,4 +54,4 @@
47=Pager
48=Cellular
49=OtherHeader
49=Customize...

View File

@ -92,9 +92,6 @@ void nsMsgBodyHandler::Initialize()
m_stripHtml = PR_TRUE;
m_messageIsHtml = PR_FALSE;
m_passedHeaders = PR_FALSE;
// set our offsets to 0 since we haven't handled any bytes yet...
m_NewsArticleOffset = 0;
m_headerBytesRead = 0;
}
@ -128,7 +125,7 @@ PRInt32 nsMsgBodyHandler::GetNextLine (char * buf, int bufSize)
// to store offline messages in berkeley format folders.
if (m_db)
{
length = GetNextLocalLine (buf, bufSize); // (2) POP
length = GetNextLocalLine (buf, bufSize); // (2) POP
}
}
@ -195,13 +192,14 @@ PRInt32 nsMsgBodyHandler::GetNextLocalLine(char * buf, int bufSize)
{
if (m_numLocalLines)
{
m_numLocalLines--; // the line count is for header and body lines
if (m_passedHeaders)
m_numLocalLines--; // the line count is only for body lines
// do we need to check the return value here?
if (m_fileSpec)
{
PRBool isEof = PR_FALSE;
nsresult rv = m_fileSpec->Eof(&isEof);
if (NS_SUCCEEDED(rv) && isEof)
if (NS_FAILED(rv) || isEof)
return -1;
PRBool wasTruncated = PR_FALSE;
@ -214,8 +212,6 @@ PRInt32 nsMsgBodyHandler::GetNextLocalLine(char * buf, int bufSize)
return -1;
}
PRInt32 nsMsgBodyHandler::ApplyTransformations (char *buf, PRInt32 length, PRBool &eatThisLine)
{
PRInt32 newLength = length;

View File

@ -164,32 +164,29 @@ nsMsgFilter::CreateTerm(nsIMsgSearchTerm **aResult)
}
NS_IMETHODIMP nsMsgFilter::GetTerm(PRInt32 termIndex,
nsMsgSearchAttribValue *attrib, /* attribute for this term */
nsMsgSearchOpValue *op, /* operator e.g. opContains */
nsIMsgSearchValue **value, /* value e.g. "Dogbert" */
PRBool *booleanAnd, /* PR_TRUE if AND is the boolean operator.
PR_FALSE if OR is the boolean operator */
char ** arbitraryHeader) /* arbitrary header specified by user.
ignore unless attrib = attribOtherHeader */
nsMsgSearchAttribValue *attrib, /* attribute for this term */
nsMsgSearchOpValue *op, /* operator e.g. opContains */
nsIMsgSearchValue **value, /* value e.g. "Dogbert" */
PRBool *booleanAnd, /* PR_TRUE if AND is the boolean operator. PR_FALSE if OR is the boolean operator */
char ** arbitraryHeader) /* arbitrary header specified by user.ignore unless attrib = attribOtherHeader */
{
nsresult rv;
if (!attrib || !op || !value || !booleanAnd || !arbitraryHeader)
return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIMsgSearchTerm> term;
rv = m_termList->QueryElementAt(termIndex, NS_GET_IID(nsIMsgSearchTerm),
nsresult rv;
nsCOMPtr<nsIMsgSearchTerm> term;
rv = m_termList->QueryElementAt(termIndex, NS_GET_IID(nsIMsgSearchTerm),
(void **)getter_AddRefs(term));
if (NS_SUCCEEDED(rv) && term)
{
term->GetAttrib(attrib);
term->GetOp(op);
term->GetValue(value);
term->GetBooleanAnd(booleanAnd);
if (*attrib == nsMsgSearchAttrib::OtherHeader)
term->GetArbitraryHeader(arbitraryHeader);
if(attrib)
term->GetAttrib(attrib);
if(op)
term->GetOp(op);
if(value)
term->GetValue(value);
if(booleanAnd)
term->GetBooleanAnd(booleanAnd);
if (attrib && arbitraryHeader)
if (*attrib > nsMsgSearchAttrib::OtherHeader && *attrib < nsMsgSearchAttrib::kNumMsgSearchAttributes)
term->GetArbitraryHeader(arbitraryHeader);
}
return NS_OK;
}

View File

@ -71,6 +71,7 @@ nsMsgFilterList::nsMsgFilterList() :
rv = NS_NewISupportsArray(getter_AddRefs(m_filters));
m_loggingEnabled = PR_FALSE;
m_curFilter = nsnull;
m_arbitraryHeaders.SetLength(0);
NS_INIT_REFCNT();
}
@ -723,6 +724,8 @@ nsresult nsMsgFilterList::SaveTextFilters(nsIOFileStream *aStream)
else
break;
}
if (NS_SUCCEEDED(err))
m_arbitraryHeaders.SetLength(0);
return err;
}
@ -871,8 +874,6 @@ nsresult nsMsgFilterList::MoveFilterAt(PRUint32 filterIndex,
NS_ENSURE_ARG((motion == nsMsgFilterMotion::up) ||
(motion == nsMsgFilterMotion::down));
nsresult rv;
PRUint32 filterCount;
m_filters->Count(&filterCount);
@ -967,6 +968,63 @@ NS_IMETHODIMP nsMsgFilterList::MatchOrChangeFilterTarget(const char *oldFolderUr
}
return rv;
}
NS_IMETHODIMP nsMsgFilterList::GetShouldDownloadArbitraryHeaders(PRBool *aResult)
{
nsresult rv = NS_OK;
if (m_arbitraryHeaders.Length() == 0)
{
PRUint32 numFilters;
rv = m_filters->Count(&numFilters);
NS_ENSURE_SUCCESS(rv,rv);
nsCOMPtr <nsIMsgFilter> filter;
nsCOMPtr <nsISupports> filterSupports;
nsMsgSearchAttribValue attrib;
nsXPIDLCString arbitraryHeader;
for (PRUint32 index = 0; index < numFilters; index++)
{
filterSupports = getter_AddRefs(m_filters->ElementAt(index));
filter = do_QueryInterface(filterSupports, &rv);
if (NS_SUCCEEDED(rv) && filter)
{
nsCOMPtr <nsISupportsArray> searchTerms;
PRUint32 numSearchTerms=0;
filter->GetSearchTerms(getter_AddRefs(searchTerms));
if (searchTerms)
searchTerms->Count(&numSearchTerms);
for (PRUint32 i=0; i< numSearchTerms;i++)
{
filter->GetTerm(i, &attrib, nsnull,nsnull,nsnull, getter_Copies(arbitraryHeader));
if (arbitraryHeader && arbitraryHeader[0])
{
if (m_arbitraryHeaders.Length() == 0)
m_arbitraryHeaders.Assign(arbitraryHeader);
else if (PL_strncasecmp(m_arbitraryHeaders, arbitraryHeader, arbitraryHeader.Length()))
{
m_arbitraryHeaders.Append(" ");
m_arbitraryHeaders.Append(arbitraryHeader);
}
}
}
}
}
}
if (m_arbitraryHeaders.Length() > 0) //if any arbitraryHeaders;
*aResult=PR_TRUE;
return NS_OK;
}
NS_IMETHODIMP nsMsgFilterList::GetArbitraryHeaders(char **aResult)
{
PRBool headers=PR_FALSE;
GetShouldDownloadArbitraryHeaders(&headers);
if (headers)
*aResult = ToNewCString(m_arbitraryHeaders);
return NS_OK;
}
#ifdef DEBUG
void nsMsgFilterList::Dump()
{

View File

@ -98,7 +98,7 @@ protected:
nsMsgFilter *m_curFilter; // filter we're filing in or out(?)
const char *m_filterFileName;
nsCOMPtr<nsISupportsArray> m_filters;
nsCString m_arbitraryHeaders;
nsCOMPtr<nsIFileSpec> m_defaultFile;
};

View File

@ -61,6 +61,10 @@ NS_IMETHODIMP nsMsgFilterService::OpenFilterList(nsIFileSpec *filterFile, nsIMsg
nsFileSpec filterSpec;
filterFile->GetFileSpec(&filterSpec);
PRBool exists;
filterFile->Exists(&exists);
if (!exists)
return NS_OK;
nsIOFileStream *fileStream = new nsIOFileStream(filterSpec);
if (!fileStream)
return NS_ERROR_OUT_OF_MEMORY;

View File

@ -280,10 +280,14 @@ nsresult nsMsgSearchValidityManager::InitOfflineMailTable ()
m_offlineMailTable->SetAvailable (nsMsgSearchAttrib::AgeInDays, nsMsgSearchOp::Is, 1);
m_offlineMailTable->SetEnabled (nsMsgSearchAttrib::AgeInDays, nsMsgSearchOp::Is, 1);
m_offlineMailTable->SetValidButNotShown (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::Contains, 1); // added for arbitrary headers
m_offlineMailTable->SetValidButNotShown (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::DoesntContain, 1);
m_offlineMailTable->SetValidButNotShown (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::Is, 1);
m_offlineMailTable->SetValidButNotShown (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::Isnt, 1);
m_offlineMailTable->SetAvailable (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::Contains, 1);
m_offlineMailTable->SetEnabled (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::Contains, 1);
m_offlineMailTable->SetAvailable (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::Is, 1);
m_offlineMailTable->SetEnabled (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::Is, 1);
m_offlineMailTable->SetAvailable (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::BeginsWith, 1);
m_offlineMailTable->SetEnabled (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::BeginsWith, 1);
m_offlineMailTable->SetAvailable (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::EndsWith, 1);
m_offlineMailTable->SetEnabled (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::EndsWith, 1);
}
@ -349,9 +353,14 @@ nsresult nsMsgSearchValidityManager::InitOnlineMailTable ()
m_onlineMailTable->SetEnabled (nsMsgSearchAttrib::AgeInDays, nsMsgSearchOp::Is, 1);
m_onlineMailTable->SetAvailable (nsMsgSearchAttrib::AgeInDays, nsMsgSearchOp::Is, 1);
m_onlineMailTable->SetValidButNotShown (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::Contains, 1); // added for arbitrary headers
m_onlineMailTable->SetValidButNotShown (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::DoesntContain, 1);
m_onlineMailTable->SetAvailable (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::Contains, 1);
m_onlineMailTable->SetEnabled (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::Contains, 1);
m_onlineMailTable->SetAvailable (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::Is, 1);
m_onlineMailTable->SetEnabled (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::Is, 1);
m_onlineMailTable->SetAvailable (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::BeginsWith, 1);
m_onlineMailTable->SetEnabled (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::BeginsWith, 1);
m_onlineMailTable->SetAvailable (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::EndsWith, 1);
m_onlineMailTable->SetEnabled (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::EndsWith, 1);
}
return err;
@ -459,11 +468,14 @@ nsresult nsMsgSearchValidityManager::InitOnlineMailFilterTable ()
m_onlineMailFilterTable->SetValidButNotShown (nsMsgSearchAttrib::AgeInDays, nsMsgSearchOp::IsLessThan, 1);
m_onlineMailFilterTable->SetValidButNotShown (nsMsgSearchAttrib::AgeInDays, nsMsgSearchOp::Is, 1);
m_onlineMailFilterTable->SetValidButNotShown (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::Contains, 1); // added for arbitrary headers
m_onlineMailFilterTable->SetValidButNotShown (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::DoesntContain, 1);
m_onlineMailFilterTable->SetValidButNotShown (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::Is, 1);
m_onlineMailFilterTable->SetValidButNotShown (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::Isnt, 1);
m_onlineMailFilterTable->SetAvailable (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::Contains, 1);
m_onlineMailFilterTable->SetEnabled (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::Contains, 1);
m_onlineMailFilterTable->SetAvailable (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::Is, 1);
m_onlineMailFilterTable->SetEnabled (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::Is, 1);
m_onlineMailFilterTable->SetAvailable (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::BeginsWith, 1);
m_onlineMailFilterTable->SetEnabled (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::BeginsWith, 1);
m_onlineMailFilterTable->SetAvailable (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::EndsWith, 1);
m_onlineMailFilterTable->SetEnabled (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::EndsWith, 1);
}
return err;

View File

@ -255,7 +255,6 @@ void nsMsgSearchBoolExpression::GenerateEncodeStr(nsCString * buffer)
nsMsgSearchIMAPOfflineMail::nsMsgSearchIMAPOfflineMail (nsIMsgSearchScopeTerm *scope, nsISupportsArray *termList) : nsMsgSearchOfflineMail(scope, termList)
{
}
@ -316,7 +315,6 @@ nsMsgSearchOfflineMail::nsMsgSearchOfflineMail (nsIMsgSearchScopeTerm *scope, ns
m_listContext = nsnull;
}
nsMsgSearchOfflineMail::~nsMsgSearchOfflineMail ()
{
// Database should have been closed when the scope term finished.
@ -511,6 +509,7 @@ nsMsgSearchOfflineMail::MatchTermsForSearch(nsIMsgDBHdr *msgToMatch,
nsIMsgDatabase *db,
PRBool *pResult)
{
return MatchTerms(msgToMatch, termList, defaultCharset, scope, db, nsnull, 0, PR_FALSE, pResult);
}
@ -568,91 +567,89 @@ nsresult nsMsgSearchOfflineMail::MatchTerms(nsIMsgDBHdr *msgToMatch,
switch (attrib)
{
case nsMsgSearchAttrib::Sender:
msgToMatch->GetAuthor(getter_Copies(matchString));
err = pTerm->MatchRfc822String (matchString, charset, charsetOverride, &result);
break;
msgToMatch->GetAuthor(getter_Copies(matchString));
err = pTerm->MatchRfc822String (matchString, charset, charsetOverride, &result);
break;
case nsMsgSearchAttrib::Subject:
{
{
msgToMatch->GetSubject(getter_Copies(matchString) /* , PR_TRUE */);
err = pTerm->MatchRfc2047String (matchString, charset, charsetOverride, &result);
}
break;
}
break;
case nsMsgSearchAttrib::ToOrCC:
{
{
PRBool boolKeepGoing;
pTerm->GetMatchAllBeforeDeciding(&boolKeepGoing);
msgToMatch->GetRecipients(getter_Copies(recipients));
err = pTerm->MatchRfc822String (recipients, charset, charsetOverride, &result);
if (boolKeepGoing == result)
{
msgToMatch->GetCcList(getter_Copies(ccList));
err = pTerm->MatchRfc822String (ccList, charset, charsetOverride, &result);
msgToMatch->GetCcList(getter_Copies(ccList));
err = pTerm->MatchRfc822String (ccList, charset, charsetOverride, &result);
}
}
break;
}
break;
case nsMsgSearchAttrib::Body:
{
nsMsgKey messageOffset;
PRUint32 lineCount;
msgToMatch->GetMessageOffset(&messageOffset);
msgToMatch->GetLineCount(&lineCount);
err = pTerm->MatchBody (scope, messageOffset, lineCount, charset, msgToMatch, db, &result);
}
break;
{
nsMsgKey messageOffset;
PRUint32 lineCount;
msgToMatch->GetMessageOffset(&messageOffset);
msgToMatch->GetLineCount(&lineCount);
err = pTerm->MatchBody (scope, messageOffset, lineCount, charset, msgToMatch, db, &result);
}
break;
case nsMsgSearchAttrib::Date:
{
PRTime date;
msgToMatch->GetDate(&date);
err = pTerm->MatchDate (date, &result);
}
break;
{
PRTime date;
msgToMatch->GetDate(&date);
err = pTerm->MatchDate (date, &result);
}
break;
case nsMsgSearchAttrib::MsgStatus:
err = pTerm->MatchStatus (msgFlags, &result);
break;
err = pTerm->MatchStatus (msgFlags, &result);
break;
case nsMsgSearchAttrib::Priority:
{
nsMsgPriorityValue msgPriority;
msgToMatch->GetPriority(&msgPriority);
err = pTerm->MatchPriority (msgPriority, &result);
}
break;
{
nsMsgPriorityValue msgPriority;
msgToMatch->GetPriority(&msgPriority);
err = pTerm->MatchPriority (msgPriority, &result);
}
break;
case nsMsgSearchAttrib::Size:
{
PRUint32 messageSize;
msgToMatch->GetMessageSize(&messageSize);
err = pTerm->MatchSize (messageSize, &result);
}
break;
{
PRUint32 messageSize;
msgToMatch->GetMessageSize(&messageSize);
err = pTerm->MatchSize (messageSize, &result);
}
break;
case nsMsgSearchAttrib::To:
msgToMatch->GetRecipients(getter_Copies(recipients));
err = pTerm->MatchRfc822String(nsCAutoString(recipients), charset, charsetOverride, &result);
break;
msgToMatch->GetRecipients(getter_Copies(recipients));
err = pTerm->MatchRfc822String(nsCAutoString(recipients), charset, charsetOverride, &result);
break;
case nsMsgSearchAttrib::CC:
msgToMatch->GetCcList(getter_Copies(ccList));
err = pTerm->MatchRfc822String (nsCAutoString(ccList), charset, charsetOverride, &result);
break;
msgToMatch->GetCcList(getter_Copies(ccList));
err = pTerm->MatchRfc822String (nsCAutoString(ccList), charset, charsetOverride, &result);
break;
case nsMsgSearchAttrib::AgeInDays:
{
PRTime date;
msgToMatch->GetDate(&date);
err = pTerm->MatchAge (date, &result);
}
break;
case nsMsgSearchAttrib::OtherHeader:
{
PRUint32 lineCount;
msgToMatch->GetLineCount(&lineCount);
nsMsgKey messageKey;
msgToMatch->GetMessageKey(&messageKey);
err = pTerm->MatchArbitraryHeader (scope, messageKey, lineCount,charset, charsetOverride,
msgToMatch, db, headers, headerSize, Filtering, &result);
}
break;
{
PRTime date;
msgToMatch->GetDate(&date);
err = pTerm->MatchAge (date, &result);
}
break;
default:
if ( attrib > nsMsgSearchAttrib::OtherHeader && attrib < nsMsgSearchAttrib::kNumMsgSearchAttributes)
{
PRUint32 lineCount;
msgToMatch->GetLineCount(&lineCount);
nsMsgKey messageKey;
msgToMatch->GetMessageOffset(&messageKey);
err = pTerm->MatchArbitraryHeader (scope, messageKey, lineCount,charset, charsetOverride,
msgToMatch, db, headers, headerSize, Filtering, &result);
}
else
err = NS_ERROR_INVALID_ARG; // ### was SearchError_InvalidAttribute
}
if (expression && NS_SUCCEEDED(err))
expression = expression->AddSearchTerm(pTerm, result); // added the term and its value to the expression tree
else
@ -705,7 +702,6 @@ nsresult nsMsgSearchOfflineMail::Search (PRBool *aDone)
NS_ConvertUCS2toUTF8 charset(folderCharset);
// Is this message a hit?
err = MatchTermsForSearch (msgDBHdr, m_searchTerms, charset.get(), m_scope, m_db, &match);
// Add search hits to the results list
if (NS_SUCCEEDED(err) && match)
{
@ -808,6 +804,11 @@ nsresult nsMsgSearchOfflineNews::OpenSummaryFile ()
nsCOMPtr <nsIDBFolderInfo> folderInfo;
nsCOMPtr <nsIMsgFolder> scopeFolder;
err = m_scope->GetFolder(getter_AddRefs(scopeFolder));
nsCOMPtr <nsIFileSpec> pathSpec;
err= scopeFolder->GetPath(getter_AddRefs(pathSpec));
PRBool exists=PR_FALSE;
err = pathSpec->Exists(&exists);
if (!exists) return NS_ERROR_FILE_NOT_FOUND;
if (NS_SUCCEEDED(err) && scopeFolder)
err = scopeFolder->GetMsgDatabase(nsnull, &m_db);
return err;
@ -863,16 +864,6 @@ nsresult nsMsgSearchValidityManager::InitLocalNewsTable()
m_localNewsTable->SetAvailable (nsMsgSearchAttrib::Date, nsMsgSearchOp::Isnt, 1);
m_localNewsTable->SetEnabled (nsMsgSearchAttrib::Date, nsMsgSearchOp::Isnt, 1);
#ifdef DOING_ARBITRARY_HEADERS
m_localNewsTable->SetAvailable (attribOtherHeader, nsMsgSearchOp::Contains, 1); // added for arbitrary headers
m_localNewsTable->SetEnabled (attribOtherHeader, nsMsgSearchOp::Contains, 1);
m_localNewsTable->SetAvailable (attribOtherHeader, nsMsgSearchOp::DoesntContain, 1);
m_localNewsTable->SetEnabled (attribOtherHeader, nsMsgSearchOp::DoesntContain, 1);
m_localNewsTable->SetAvailable (attribOtherHeader, nsMsgSearchOp::Is, 1);
m_localNewsTable->SetEnabled (attribOtherHeader, nsMsgSearchOp::Is, 1);
m_localNewsTable->SetAvailable (attribOtherHeader, nsMsgSearchOp::Isnt, 1);
m_localNewsTable->SetEnabled (attribOtherHeader, nsMsgSearchOp::Isnt, 1);
#endif
m_localNewsTable->SetAvailable (nsMsgSearchAttrib::AgeInDays, nsMsgSearchOp::IsGreaterThan, 1);
m_localNewsTable->SetEnabled (nsMsgSearchAttrib::AgeInDays, nsMsgSearchOp::IsGreaterThan, 1);
m_localNewsTable->SetAvailable (nsMsgSearchAttrib::AgeInDays, nsMsgSearchOp::IsLessThan, 1);
@ -885,6 +876,16 @@ nsresult nsMsgSearchValidityManager::InitLocalNewsTable()
m_localNewsTable->SetAvailable (nsMsgSearchAttrib::MsgStatus, nsMsgSearchOp::Isnt, 1);
m_localNewsTable->SetEnabled (nsMsgSearchAttrib::MsgStatus, nsMsgSearchOp::Isnt, 1);
m_localNewsTable->SetAvailable (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::Contains, 1);
m_localNewsTable->SetEnabled (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::Contains, 1);
m_localNewsTable->SetAvailable (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::Is, 1);
m_localNewsTable->SetEnabled (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::Is, 1);
m_localNewsTable->SetAvailable (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::BeginsWith, 1);
m_localNewsTable->SetEnabled (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::BeginsWith, 1);
m_localNewsTable->SetAvailable (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::EndsWith, 1);
m_localNewsTable->SetEnabled (nsMsgSearchAttrib::OtherHeader, nsMsgSearchOp::EndsWith, 1);
}
return err;

View File

@ -96,7 +96,6 @@ protected:
PRBool *pResult);
nsIMsgDatabase *m_db;
nsCOMPtr<nsISimpleEnumerator> m_listContext;
void CleanUpScope();
};

View File

@ -80,6 +80,7 @@ const char *nsMsgSearchAdapter::m_kImapCharset = " CHARSET ";
static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID);
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
#define PREF_CUSTOM_HEADERS "mailnews.customHeaders"
NS_IMETHODIMP nsMsgSearchAdapter::FindTargetFolder(const nsMsgResultElement *,nsIMsgFolder * *)
{
@ -424,25 +425,6 @@ nsresult nsMsgSearchAdapter::EncodeImapTerm (nsIMsgSearchTerm *term, PRBool real
whichMnemonic = m_kImapBody;
excludeHeader = PR_TRUE;
break;
case nsMsgSearchAttrib::OtherHeader: // arbitrary header? if so create arbitrary header string
{
nsXPIDLCString arbitraryHeaderTerm;
term->GetArbitraryHeader(getter_Copies(arbitraryHeaderTerm));
if (nsCRT::strlen((const char *) arbitraryHeaderTerm) > 0)
{
arbitraryHeader = new char [nsCRT::strlen((const char *)arbitraryHeaderTerm) + 6]; // 6 bytes for SPACE \" .... \" SPACE
if (!arbitraryHeader)
return NS_ERROR_OUT_OF_MEMORY;
arbitraryHeader[0] = '\0';
PL_strcat(arbitraryHeader, " \"");
PL_strcat(arbitraryHeader, (const char *)arbitraryHeaderTerm);
PL_strcat(arbitraryHeader, "\" ");
whichMnemonic = arbitraryHeader;
}
else
return NS_ERROR_FAILURE;
}
break;
case nsMsgSearchAttrib::AgeInDays: // added for searching online for age in days...
// for AgeInDays, we are actually going to perform a search by date, so convert the operations for age
// to the IMAP mnemonics that we would use for date!
@ -510,8 +492,29 @@ nsresult nsMsgSearchAdapter::EncodeImapTerm (nsIMsgSearchTerm *term, PRBool real
}
break;
default:
if ( attrib > nsMsgSearchAttrib::OtherHeader && attrib < nsMsgSearchAttrib::kNumMsgSearchAttributes)
{
nsXPIDLCString arbitraryHeaderTerm;
term->GetArbitraryHeader(getter_Copies(arbitraryHeaderTerm));
if (nsCRT::strlen((const char *) arbitraryHeaderTerm) > 0)
{
arbitraryHeader = new char [nsCRT::strlen((const char *)arbitraryHeaderTerm) + 6]; // 6 bytes for SPACE \" .... \" SPACE
if (!arbitraryHeader)
return NS_ERROR_OUT_OF_MEMORY;
arbitraryHeader[0] = '\0';
PL_strcat(arbitraryHeader, " \"");
PL_strcat(arbitraryHeader, (const char *)arbitraryHeaderTerm);
PL_strcat(arbitraryHeader, "\" ");
whichMnemonic = arbitraryHeader;
}
else
return NS_ERROR_FAILURE;
}
else
{
NS_ASSERTION(PR_FALSE, "invalid search operator");
return NS_ERROR_INVALID_ARG;
return NS_ERROR_INVALID_ARG;
}
}
char *value = "";
@ -1004,25 +1007,36 @@ NS_IMPL_ISUPPORTS1(nsMsgSearchValidityManager, nsIMsgSearchValidityManager)
nsresult nsMsgSearchValidityManager::GetTable (int whichTable, nsIMsgSearchValidityTable **ppOutTable)
{
NS_ENSURE_ARG(ppOutTable);
nsresult err = NS_OK;
*ppOutTable = nsnull;
nsCOMPtr<nsIPref> pref = do_GetService(NS_PREF_CONTRACTID, &err);
nsXPIDLCString customHeaders;
if (NS_SUCCEEDED(err) && pref)
pref->GetCharPref(PREF_CUSTOM_HEADERS, getter_Copies(customHeaders));
switch (whichTable)
{
case nsMsgSearchScope::offlineMail:
if (!m_offlineMailTable)
err = InitOfflineMailTable ();
if (!m_offlineMailTable)
err = InitOfflineMailTable ();
if (customHeaders && m_offlineMailTable)
err = InitOtherHeadersInTable(m_offlineMailTable, customHeaders.get());
*ppOutTable = m_offlineMailTable;
break;
case nsMsgSearchScope::onlineMail:
if (!m_onlineMailTable)
err = InitOnlineMailTable ();
err = InitOnlineMailTable ();
if (customHeaders && m_onlineMailTable)
err = InitOtherHeadersInTable(m_onlineMailTable, customHeaders.get());
*ppOutTable = m_onlineMailTable;
break;
case nsMsgSearchScope::onlineMailFilter:
if (!m_onlineMailFilterTable)
err = InitOnlineMailFilterTable ();
if (customHeaders && m_onlineMailFilterTable)
err = InitOtherHeadersInTable(m_onlineMailFilterTable, customHeaders.get());
*ppOutTable = m_onlineMailFilterTable;
break;
case nsMsgSearchScope::news:
@ -1033,6 +1047,8 @@ nsresult nsMsgSearchValidityManager::GetTable (int whichTable, nsIMsgSearchValid
case nsMsgSearchScope::localNews:
if (!m_localNewsTable)
err = InitLocalNewsTable();
if (customHeaders && m_localNewsTable)
err = InitOtherHeadersInTable(m_localNewsTable, customHeaders.get());
*ppOutTable = m_localNewsTable;
break;
#ifdef DOING_EXNEWSSEARCH
@ -1071,4 +1087,35 @@ nsMsgSearchValidityManager::NewTable(nsIMsgSearchValidityTable **aTable)
return NS_OK;
}
nsresult
nsMsgSearchValidityManager::InitOtherHeadersInTable (nsIMsgSearchValidityTable *aTable, const char *customHeaders)
{
PRUint32 strlen = PL_strlen(customHeaders);
PRUint32 numHeaders=0;
for (PRUint32 i=0;i <strlen; i++)
if (customHeaders[i] == ':')
numHeaders++;
numHeaders++;
NS_ASSERTION(nsMsgSearchAttrib::OtherHeader + numHeaders < nsMsgSearchAttrib::kNumMsgSearchAttributes, "more headers than the table can hold");
for (i=nsMsgSearchAttrib::OtherHeader+1;i< (nsMsgSearchAttrib::OtherHeader + numHeaders+1) && nsMsgSearchAttrib::kNumMsgSearchAttributes;i++)
{
aTable->SetAvailable (i, nsMsgSearchOp::Contains, 1); // added for arbitrary headers
aTable->SetEnabled (i, nsMsgSearchOp::Contains, 1);
aTable->SetAvailable (i, nsMsgSearchOp::DoesntContain, 1);
aTable->SetEnabled (i, nsMsgSearchOp::DoesntContain, 1);
aTable->SetAvailable (i, nsMsgSearchOp::Is, 1);
aTable->SetEnabled (i, nsMsgSearchOp::Is, 1);
aTable->SetAvailable (i, nsMsgSearchOp::Isnt, 1);
aTable->SetEnabled (i, nsMsgSearchOp::Isnt, 1);
}
//because custom headers can change; so reset the table for those which are no longer used.
for (PRUint32 j=nsMsgSearchAttrib::OtherHeader+numHeaders+1; j < nsMsgSearchAttrib::kNumMsgSearchAttributes; j++)
{
for (PRUint32 k=0; k < nsMsgSearchOp::kNumMsgSearchOperators; k++)
{
aTable->SetAvailable(j,k,0);
aTable->SetEnabled(j,k,0);
}
}
return NS_OK;
}

View File

@ -56,6 +56,7 @@
#include "nsIMimeConverter.h"
#include "nsMsgMimeCID.h"
#include "nsTime.h"
#include "nsIPref.h"
//---------------------------------------------------------------------------
// nsMsgSearchTerm specifies one criterion, e.g. name contains phil
@ -65,7 +66,7 @@
//-----------------------------------------------------------------------------
//-------------------- Implementation of nsMsgSearchTerm -----------------------
//-----------------------------------------------------------------------------
#define MAILNEWS_CUSTOM_HEADERS "mailnews.customHeaders"
typedef struct
{
@ -101,9 +102,34 @@ nsresult NS_MsgGetAttributeFromString(const char *string, PRInt16 *attrib)
*attrib = SearchAttribEntryTable[idxAttrib].attrib;
break;
}
}
}
if (!found)
*attrib = nsMsgSearchAttrib::OtherHeader; // assume arbitrary header if we could not find the header in the table
{
nsresult rv;
*attrib = nsMsgSearchAttrib::OtherHeader;
nsCOMPtr <nsIPref> prefs = do_GetService(NS_PREF_CONTRACTID, &rv);
nsXPIDLCString headers;
if (NS_SUCCEEDED(rv) && prefs)
prefs->GetCharPref(MAILNEWS_CUSTOM_HEADERS, getter_Copies(headers));
if (headers)
{
char *headersString = ToNewCString(headers);
char *newStr=nsnull;
char *token = nsCRT::strtok(headersString,": ", &newStr);
PRUint32 i=1; //headers start from 50 onwards...
while (token)
{
if (nsCRT::strcasecmp(token, string) == 0)
{
*attrib = nsMsgSearchAttrib::OtherHeader+i;
break;
}
token = nsCRT::strtok(newStr,": ", &newStr);
i++;
}
nsMemory::Free(headersString);
}
}
return NS_OK; // we always succeed now
}
@ -276,7 +302,7 @@ nsMsgSearchTerm::nsMsgSearchTerm (
NS_INIT_REFCNT();
m_operator = op;
m_booleanOp = (booleanAND) ? nsMsgSearchBooleanOp::BooleanAND : nsMsgSearchBooleanOp::BooleanOR;
if (attrib == nsMsgSearchAttrib::OtherHeader && arbitraryHeader)
if (attrib > nsMsgSearchAttrib::OtherHeader && attrib < nsMsgSearchAttrib::kNumMsgSearchAttributes && arbitraryHeader)
m_arbitraryHeader = arbitraryHeader;
m_attribute = attrib;
@ -295,7 +321,7 @@ nsMsgSearchTerm::nsMsgSearchTerm (
m_operator = op;
m_attribute = attrib;
m_booleanOp = boolOp;
if (attrib == nsMsgSearchAttrib::OtherHeader && arbitraryHeader)
if (attrib > nsMsgSearchAttrib::OtherHeader && attrib < nsMsgSearchAttrib::kNumMsgSearchAttributes && arbitraryHeader)
m_arbitraryHeader = arbitraryHeader;
nsMsgResultElement::AssignValues (val, &m_value);
}
@ -412,7 +438,7 @@ nsresult nsMsgSearchTerm::EnStreamNew (nsCString &outStream)
if (ret != NS_OK)
return ret;
if (m_attribute == nsMsgSearchAttrib::OtherHeader) // if arbitrary header, use it instead!
if (m_attribute > nsMsgSearchAttrib::OtherHeader && m_attribute < nsMsgSearchAttrib::kNumMsgSearchAttributes) // if arbitrary header, use it instead!
{
outputStr = "\"";
outputStr += m_arbitraryHeader;
@ -441,9 +467,8 @@ nsresult nsMsgSearchTerm::ParseValue(char *inStream)
if (IS_STRING_ATTRIBUTE(m_attribute))
{
PRBool quoteVal = PR_FALSE;
while (nsString::IsSpace(*inStream))
inStream++;
while (nsString::IsSpace(*inStream))
inStream++;
// need to remove pair of '"', if present
if (*inStream == '"')
{
@ -530,7 +555,7 @@ nsMsgSearchTerm::ParseAttribute(char *inStream)
err = NS_MsgGetAttributeFromString(inStream, &attributeVal);
nsMsgSearchAttribValue attrib = (nsMsgSearchAttribValue) attributeVal;
if (attrib == nsMsgSearchAttrib::OtherHeader) // if we are dealing with an arbitrary header....
if (attrib > nsMsgSearchAttrib::OtherHeader && attrib < nsMsgSearchAttrib::kNumMsgSearchAttributes) // if we are dealing with an arbitrary header....
m_arbitraryHeader = inStream;
return attrib;
@ -646,11 +671,11 @@ nsresult nsMsgSearchTerm::MatchArbitraryHeader (nsIMsgSearchScopeTerm *scope,
if (buf)
{
PRBool searchingHeaders = PR_TRUE;
while (searchingHeaders && bodyHandler->GetNextLine(buf, kBufSize))
while (searchingHeaders && (bodyHandler->GetNextLine(buf, kBufSize) >=0))
{
char * buf_end = buf + PL_strlen(buf);
int headerLength = m_arbitraryHeader.Length();
if (m_arbitraryHeader.Equals(buf))
if (!PL_strncasecmp(buf, m_arbitraryHeader.get(),headerLength))
{
char * headerValue = buf + headerLength; // value occurs after the header name...
if (headerValue < buf_end && headerValue[0] == ':') // + 1 to account for the colon which is MANDATORY

View File

@ -64,10 +64,6 @@ public:
return iid;
}
NS_IMETHOD GetArbitraryHeaders(nsIImapProtocol* aProtocol,
GenericInfo* aInfo) = 0;
NS_IMETHOD GetShouldDownloadArbitraryHeaders(nsIImapProtocol* aProtocol,
GenericInfo* aInfo) = 0;
NS_IMETHOD HeaderFetchCompleted(nsIImapProtocol* aProtocol) = 0;
NS_IMETHOD UpdateSecurityStatus(nsIImapProtocol* aProtocol) = 0;
// ****

View File

@ -66,5 +66,7 @@ interface nsIImapServerSink : nsISupports {
/* this is a bogus method on this interface but i need it until misc. sink is scriptable.. */
void RemoveChannelFromUrl(in nsIMsgMailNewsUrl aUrl, in unsigned long statusCode);
readonly attribute string arbitraryHeaders;
readonly attribute boolean shouldDownloadArbitraryHeaders;
};

View File

@ -3439,6 +3439,29 @@ nsImapIncomingServer::GetNewMessagesAllFolders(nsIMsgFolder *aRootFolder, nsIMsg
return retval;
}
NS_IMETHODIMP
nsImapIncomingServer::GetShouldDownloadArbitraryHeaders(PRBool *aResult)
{
nsresult rv = NS_OK; //for now checking for filters is enough
nsCOMPtr <nsIMsgFilterList> filterList; //later on we might have to check for MDN ;
if (!mFilterList)
GetFilterList(getter_AddRefs(filterList));
if (mFilterList)
rv = mFilterList->GetShouldDownloadArbitraryHeaders(aResult);
else
*aResult = PR_FALSE;
return rv;
}
NS_IMETHODIMP
nsImapIncomingServer::GetArbitraryHeaders(char **aResult)
{
nsresult rv =NS_OK;
if (mFilterList)
rv = mFilterList->GetArbitraryHeaders(aResult);
return rv;
}
NS_IMETHODIMP
nsImapIncomingServer::OnUserOrHostNameChanged(const char *oldName, const char *newName)
{
@ -3461,3 +3484,4 @@ nsImapIncomingServer::OnUserOrHostNameChanged(const char *oldName, const char *n
ResetFoldersToUnverified(nsnull);
return NS_OK;
}

View File

@ -107,6 +107,7 @@ static NS_DEFINE_CID(kPrefCID, NS_PREF_CID);
#define FOUR_K 4096
#define MAILNEWS_CUSTOM_HEADERS "mailnews.customHeaders"
/*
Copies the contents of srcDir into destDir.
@ -4326,20 +4327,6 @@ nsImapMailFolder::AddSearchResult(nsIImapProtocol* aProtocol,
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsImapMailFolder::GetArbitraryHeaders(nsIImapProtocol* aProtocol,
GenericInfo* aInfo)
{
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsImapMailFolder::GetShouldDownloadArbitraryHeaders(nsIImapProtocol* aProtocol,
GenericInfo* aInfo)
{
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsImapMailFolder::HeaderFetchCompleted(nsIImapProtocol* aProtocol)
{

View File

@ -247,10 +247,6 @@ public:
// nsIImapMiscellaneousSink methods
NS_IMETHOD AddSearchResult(nsIImapProtocol* aProtocol,
const char* searchHitLine);
NS_IMETHOD GetArbitraryHeaders(nsIImapProtocol* aProtocol,
GenericInfo* aInfo);
NS_IMETHOD GetShouldDownloadArbitraryHeaders(nsIImapProtocol* aProtocol,
GenericInfo* aInfo);
NS_IMETHOD HeaderFetchCompleted(nsIImapProtocol* aProtocol);
NS_IMETHOD UpdateSecurityStatus(nsIImapProtocol* aProtocol);
// ****

View File

@ -2260,49 +2260,18 @@ nsresult nsImapProtocol::BeginMessageDownLoad(
return rv;
}
PRBool
nsImapProtocol::GetShouldDownloadArbitraryHeaders()
void
nsImapProtocol::GetShouldDownloadArbitraryHeaders(PRBool *aResult)
{
// *** allocate instead of using local variable to be thread save ***
GenericInfo *aInfo = (GenericInfo*) PR_CALLOC(sizeof(GenericInfo));
const char *hostName = GetImapHostName();
PRBool rv;
aInfo->rv = PR_TRUE; // default
aInfo->hostName = PL_strdup (hostName);
if (m_imapMiscellaneousSink)
{
m_imapMiscellaneousSink->GetShouldDownloadArbitraryHeaders(this, aInfo);
WaitForFEEventCompletion();
}
rv = aInfo->rv;
if (aInfo->hostName)
PL_strfree(aInfo->hostName);
if (aInfo->c)
PL_strfree(aInfo->c);
PR_Free(aInfo);
return rv;
if (m_imapServerSink)
m_imapServerSink->GetShouldDownloadArbitraryHeaders(aResult);
}
char*
nsImapProtocol::GetArbitraryHeadersToDownload()
void
nsImapProtocol::GetArbitraryHeadersToDownload(char **aResult)
{
// *** allocate instead of using local variable to be thread save ***
GenericInfo *aInfo = (GenericInfo*) PR_CALLOC(sizeof(GenericInfo));
const char *hostName = GetImapHostName();
char *rv = nsnull;
aInfo->rv = PR_TRUE; // default
aInfo->hostName = PL_strdup (hostName);
if (m_imapMiscellaneousSink)
{
m_imapMiscellaneousSink->GetShouldDownloadArbitraryHeaders(this, aInfo);
WaitForFEEventCompletion();
}
if (aInfo->hostName)
PL_strfree(aInfo->hostName);
rv = aInfo->c;
PR_Free(aInfo);
return rv;
if (m_imapServerSink)
m_imapServerSink->GetArbitraryHeaders(aResult);
}
static void PRTime2Seconds(PRTime prTime, PRInt32 *seconds)
@ -2565,19 +2534,18 @@ nsImapProtocol::FetchMessage(const char * messageIds,
{
PRUint32 server_capabilityFlags = GetServerStateParser().GetCapabilityFlag();
PRBool aolImapServer = ((server_capabilityFlags & kAOLImapCapability) != 0);
PRBool useArbitraryHeaders = GetShouldDownloadArbitraryHeaders(); // checks filter headers, etc.
PRBool useArbitraryHeaders = PR_FALSE;
GetShouldDownloadArbitraryHeaders(&useArbitraryHeaders); // checks filter headers, etc.
if (/***** Fix me *** gOptimizedHeaders && */// preference -- able to turn it off
useArbitraryHeaders) // if it's ok -- no filters on any header, etc.
{
char *headersToDL = nsnull;
char *what = nsnull;
const char *dbHeaders = (gUseEnvelopeCmd) ? IMAP_DB_HEADERS : IMAP_ENV_AND_DB_HEADERS;
char *arbitraryHeaders = GetArbitraryHeadersToDownload();
nsXPIDLCString arbitraryHeaders;
GetArbitraryHeadersToDownload(getter_Copies(arbitraryHeaders));
if (arbitraryHeaders)
{
headersToDL = PR_smprintf("%s %s",dbHeaders, arbitraryHeaders);
PR_Free(arbitraryHeaders);
}
headersToDL = PR_smprintf("%s %s",dbHeaders, arbitraryHeaders.get());
else
headersToDL = nsCRT::strdup(dbHeaders);

View File

@ -174,8 +174,8 @@ public:
static void EscapeUserNamePasswordString(const char *strToEscape, nsCString *resultStr);
// used to start fetching a message.
PRBool GetShouldDownloadArbitraryHeaders();
char *GetArbitraryHeadersToDownload();
void GetShouldDownloadArbitraryHeaders(PRBool *aResult);
void GetArbitraryHeadersToDownload(char **aResult);
virtual void AdjustChunkSize();
virtual void FetchMessage(const char * messageIds,
nsIMAPeFetchFields whatToFetch,

View File

@ -369,64 +369,6 @@ nsImapMiscellaneousSinkProxy::~nsImapMiscellaneousSinkProxy()
NS_IMPL_THREADSAFE_ISUPPORTS1(nsImapMiscellaneousSinkProxy, nsIImapMiscellaneousSink)
NS_IMETHODIMP
nsImapMiscellaneousSinkProxy::GetArbitraryHeaders(nsIImapProtocol* aProtocol,
GenericInfo* aInfo)
{
nsresult res = NS_OK;
NS_PRECONDITION (aInfo, "Oops... null aInfo");
if(!aInfo)
return NS_ERROR_NULL_POINTER;
NS_ASSERTION (m_protocol == aProtocol, "Ooh ooh, wrong protocol");
if (PR_GetCurrentThread() == m_thread)
{
GetArbitraryHeadersProxyEvent *ev =
new GetArbitraryHeadersProxyEvent(this, aInfo);
if(nsnull == ev)
res = NS_ERROR_OUT_OF_MEMORY;
else
ev->PostEvent(m_eventQueue);
}
else
{
res = m_realImapMiscellaneousSink->GetArbitraryHeaders(aProtocol, aInfo);
}
return res;
}
NS_IMETHODIMP
nsImapMiscellaneousSinkProxy::GetShouldDownloadArbitraryHeaders(
nsIImapProtocol* aProtocol, GenericInfo* aInfo)
{
nsresult res = NS_OK;
NS_PRECONDITION (aInfo, "Oops... null aInfo");
if(!aInfo)
return NS_ERROR_NULL_POINTER;
NS_ASSERTION (m_protocol == aProtocol, "Ooh ooh, wrong protocol");
if (PR_GetCurrentThread() == m_thread)
{
GetShouldDownloadArbitraryHeadersProxyEvent *ev =
new GetShouldDownloadArbitraryHeadersProxyEvent(this, aInfo);
if(nsnull == ev)
res = NS_ERROR_OUT_OF_MEMORY;
else
{
ev->SetNotifyCompletion(PR_TRUE);
ev->PostEvent(m_eventQueue);
}
}
else
{
res =
m_realImapMiscellaneousSink->GetShouldDownloadArbitraryHeaders(aProtocol,
aInfo);
aProtocol->NotifyFEEventCompletion();
}
return res;
}
NS_IMETHODIMP
nsImapMiscellaneousSinkProxy::HeaderFetchCompleted(nsIImapProtocol* aProtocol)
{
@ -964,52 +906,6 @@ nsImapMiscellaneousSinkProxyEvent::~nsImapMiscellaneousSinkProxyEvent()
NS_IF_RELEASE (m_proxy);
}
GetArbitraryHeadersProxyEvent::GetArbitraryHeadersProxyEvent(
nsImapMiscellaneousSinkProxy* aProxy, GenericInfo* aInfo) :
nsImapMiscellaneousSinkProxyEvent(aProxy)
{
NS_ASSERTION (aInfo, "Oops... a null info");
m_info = aInfo;
}
GetArbitraryHeadersProxyEvent::~GetArbitraryHeadersProxyEvent()
{
}
NS_IMETHODIMP
GetArbitraryHeadersProxyEvent::HandleEvent()
{
nsresult res = m_proxy->m_realImapMiscellaneousSink->GetArbitraryHeaders(
m_proxy->m_protocol, m_info);
if (m_notifyCompletion)
m_proxy->m_protocol->NotifyFEEventCompletion();
return res;
}
GetShouldDownloadArbitraryHeadersProxyEvent::GetShouldDownloadArbitraryHeadersProxyEvent(
nsImapMiscellaneousSinkProxy* aProxy, GenericInfo* aInfo) :
nsImapMiscellaneousSinkProxyEvent(aProxy)
{
NS_ASSERTION (aInfo, "Oops... a null info");
m_info = aInfo;
}
GetShouldDownloadArbitraryHeadersProxyEvent::~GetShouldDownloadArbitraryHeadersProxyEvent()
{
}
NS_IMETHODIMP
GetShouldDownloadArbitraryHeadersProxyEvent::HandleEvent()
{
nsresult res =
m_proxy->m_realImapMiscellaneousSink->GetShouldDownloadArbitraryHeaders(
m_proxy->m_protocol, m_info);
if (m_notifyCompletion)
m_proxy->m_protocol->NotifyFEEventCompletion();
return res;
}
HeaderFetchCompletedProxyEvent::HeaderFetchCompletedProxyEvent(
nsImapMiscellaneousSinkProxy* aProxy) :
nsImapMiscellaneousSinkProxyEvent(aProxy)

View File

@ -113,10 +113,6 @@ public:
NS_DECL_ISUPPORTS
NS_IMETHOD GetArbitraryHeaders(nsIImapProtocol* aProtocol,
GenericInfo* aInfo);
NS_IMETHOD GetShouldDownloadArbitraryHeaders(nsIImapProtocol* aProtocol,
GenericInfo* aInfo);
NS_IMETHOD HeaderFetchCompleted(nsIImapProtocol* aProtocol);
NS_IMETHOD UpdateSecurityStatus(nsIImapProtocol* aProtocol);
// ****
@ -240,25 +236,6 @@ struct nsImapMiscellaneousSinkProxyEvent : public nsImapEvent
nsImapMiscellaneousSinkProxy* m_proxy;
};
struct GetArbitraryHeadersProxyEvent : public nsImapMiscellaneousSinkProxyEvent
{
GetArbitraryHeadersProxyEvent(nsImapMiscellaneousSinkProxy* aProxy,
GenericInfo* aInfo);
virtual ~GetArbitraryHeadersProxyEvent();
NS_IMETHOD HandleEvent();
GenericInfo *m_info; // pass in handle we don't own it
};
struct GetShouldDownloadArbitraryHeadersProxyEvent :
public nsImapMiscellaneousSinkProxyEvent
{
GetShouldDownloadArbitraryHeadersProxyEvent(
nsImapMiscellaneousSinkProxy* aProxy, GenericInfo* aInfo);
virtual ~GetShouldDownloadArbitraryHeadersProxyEvent();
NS_IMETHOD HandleEvent();
GenericInfo *m_info; // pass in handle we don't own it
};
struct HeaderFetchCompletedProxyEvent : public nsImapMiscellaneousSinkProxyEvent
{
HeaderFetchCompletedProxyEvent(nsImapMiscellaneousSinkProxy* aProxy);

View File

@ -140,6 +140,8 @@ messenger.jar:
content/messenger/searchTermOverlay.xul (base/search/resources/content/searchTermOverlay.xul)
content/messenger/FilterListDialog.xul (base/search/resources/content/FilterListDialog.xul)
content/messenger/FilterListDialog.js (base/search/resources/content/FilterListDialog.js)
content/messenger/CustomHeaders.xul (base/search/resources/content/CustomHeaders.xul)
content/messenger/CustomHeaders.js (base/search/resources/content/CustomHeaders.js)
content/messenger/FilterEditor.xul (base/search/resources/content/FilterEditor.xul)
content/messenger/FilterEditor.js (base/search/resources/content/FilterEditor.js)
content/messenger/mail-offline.js (base/resources/content/mail-offline.js)
@ -204,11 +206,13 @@ en-US.jar:
locale/en-US/messenger/offline.properties (base/resources/locale/en-US/offline.properties)
locale/en-US/messenger/SearchDialog.dtd (base/search/resources/locale/en-US/SearchDialog.dtd)
locale/en-US/messenger/FilterListDialog.dtd (base/search/resources/locale/en-US/FilterListDialog.dtd)
locale/en-US/messenger/CustomHeaders.dtd (base/search/resources/locale/en-US/CustomHeaders.dtd)
locale/en-US/messenger/FilterEditor.dtd (base/search/resources/locale/en-US/FilterEditor.dtd)
locale/en-US/messenger/search-attributes.properties (base/search/resources/locale/en-US/search-attributes.properties)
locale/en-US/messenger/search-operators.properties (base/search/resources/locale/en-US/search-operators.properties)
locale/en-US/messenger/search.properties (base/search/resources/locale/en-US/search.properties)
locale/en-US/messenger/filter.properties (base/search/resources/locale/en-US/filter.properties)
locale/en-US/messenger/custom.properties (base/search/resources/locale/en-US/custom.properties)
locale/en-US/messenger/searchTermOverlay.dtd (base/search/resources/locale/en-US/searchTermOverlay.dtd)
locale/en-US/messenger/messengercompose/pref-composing_messages.dtd (compose/prefs/resources/locale/en-US/pref-composing_messages.dtd)
locale/en-US/messenger/messengercompose/pref-formatting.dtd (compose/prefs/resources/locale/en-US/pref-formatting.dtd)