fix for #59638. cross folder navigation in the stand alone msg window

doesn't load the next unread message.  thanks to ssu for the initial patch,
and neil for the suggestions.  r/sr=bienvenu

fix for #49305.  in "view all headers" mode, we only see the last header
for headers where multiple headers are legal.  thanks to richard.li@sun.com
for the initial patch.  r/sr=bienvenu

fix for #179803. when we added mail views, we added "Sender is[n't] in addressbook"
support to filter / search / views, but it left us with two "Sender" menuitems.
this code unifies them into one.  on disk (for filters and views) both the old
way ("from in ab") and the new way ("from") work, so there isn't a migration issue.
r/sr=bienvenu
This commit is contained in:
sspitzer%netscape.com 2002-12-11 04:28:05 +00:00
Родитель 8a962ca347
Коммит cbb05359cf
16 изменённых файлов: 251 добавлений и 158 удалений

Просмотреть файл

@ -461,6 +461,25 @@
</getter>
</property>
<property name="optargets" readonly="true">
<getter>
<![CDATA[
var forAttrs = this.getAttribute("opfor");
if (!forAttrs) return null;
var optargetIds = forAttrs.split(",");
if (optargetIds.length == 0) return null;
var optargets = new Array;
var j=0;
for (var i=0; i<optargetIds.length;i++) {
var optarget = document.getElementById(optargetIds[i]);
if (optarget) optargets[j++] = optarget;
}
return optargets;
]]>
</getter>
</property>
<!-- value forwards to the internal menulist's "value" attribute -->
<property name="value" onget="return document.getAnonymousNodes(this)[0].selectedItem.getAttribute('value');">
<setter>
@ -473,12 +492,19 @@
// now notify targets of new parent's value
var targets = this.targets;
if (targets) {
for (var i=0; i< targets.length; i++) {
for (var i=0; i < targets.length; i++) {
targets[i].parentValue = val;
}
} else {
//dump("Doh! No targets!\n");
}
// now notify optargets of new op parent's value
var optargets = this.optargets;
if (optargets) {
for (i=0; i < optargets.length; i++) {
optargets[i].opParentValue = val;
}
}
return val;
]]>
</setter>
@ -543,10 +569,17 @@
// notify targets
var targets = this.targets;
if (targets) {
for (var i=0; i< targets.length; i++) {
for (var i=0; i < targets.length; i++) {
targets[i].parentValue = menulist.value;
}
}
var optargets = this.optargets;
if (optargets) {
for (i=0; i < optargets.length; i++) {
optargets[i].opParentValue = menulist.value;
}
}
]]>
</body>
</method>
@ -621,8 +654,8 @@
<!-- searchvalue - a widget which dynamically changes it's user interface
depending on what type of data it's supposed to be showing
currently handles arbitrary text entry, and menulists for priority and
status
currently handles arbitrary text entry, and menulists for
priority, status, junk status and addressbook
-->
<binding id="searchvalue" name="searchValue">
<content>
@ -675,9 +708,56 @@
</xul:menulist>
</content>
<implementation>
<field name="internalOperator">null</field>
<field name="internalAttribute">null</field>
<field name="internalValue">null</field>
<property name="opParentValue" onget="return this.internalOperator;">
<setter>
<![CDATA[
// noop if we're not changing it
if (this.internalOperator == val) return val;
// if it's not sender, we don't care
if (this.searchAttribute != Components.interfaces.nsMsgSearchAttrib.Sender) {
this.internalOperator = val;
return val;
}
var children = document.getAnonymousNodes(this);
if (val == Components.interfaces.nsMsgSearchOp.IsntInAB ||
val == Components.interfaces.nsMsgSearchOp.IsInAB) {
// if the old internalOperator was
// IsntInAB or IsInAB, and the new internalOperator is
// IsntInAB or IsInAB, noop because the search value
// was an ab type, and it still is.
// otherwise, switch to the ab picker and select the PAB
if (this.internalOperator != Components.interfaces.nsMsgSearchOp.IsntInAB &&
this.internalOperator != Components.interfaces.nsMsgSearchOp.IsInAB) {
var abs = children[4].getElementsByAttribute("value", "moz-abmdbdirectory://abook.mab");
if (abs.length > 0)
children[4].selectedItem = abs[0];
this.setAttribute("selectedIndex", "4");
}
}
else {
// if the old internalOperator wasn't
// IsntInAB or IsInAB, and the new internalOperator isn't
// IsntInAB or IsInAB, noop because the search value
// wasn't an ab type, and it still isn't.
// otherwise, switch to the textbox and clear it
if (this.internalOperator == Components.interfaces.nsMsgSearchOp.IsntInAB ||
this.internalOperator == Components.interfaces.nsMsgSearchOp.IsInAB) {
children[0].value = "";
this.setAttribute("selectedIndex", "0");
}
}
this.internalOperator = val;
return val;
]]>
</setter>
</property>
<!-- parentValue forwards to the attribute -->
<property name="parentValue" onset="return this.searchAttribute=val;"
onget="return this.searchAttribute;"/>
@ -687,6 +767,10 @@
// noop if we're not changing it
if (this.internalAttribute == val) return val;
this.internalAttribute = val;
// if the searchAttribute changing, null out the internalOperator
this.internalOperator = null;
// we inherit from a deck, so just use it's index attribute
// to hide/show widgets
if (val == Components.interfaces.nsMsgSearchAttrib.Priority)
@ -695,13 +779,12 @@
this.setAttribute("selectedIndex", "2");
else if (val == Components.interfaces.nsMsgSearchAttrib.Date)
this.setAttribute("selectedIndex", "3");
else if (val == Components.interfaces.nsMsgSearchAttrib.SenderInAddressBook)
{
var children = document.getAnonymousNodes(this);
var abs = children[4].getElementsByAttribute("value", "moz-abmdbdirectory://abook.mab");
if (abs.length > 0)
children[4].selectedItem = abs[0];
this.setAttribute("selectedIndex", "4");
else if (val == Components.interfaces.nsMsgSearchAttrib.Sender) {
// since the internalOperator is null
// this is the same as the initial state
// the initial state for Sender isn't an ab type search
// it's a text search, so show the textbox
this.setAttribute("selectedIndex", "0");
}
else if (val == Components.interfaces.nsMsgSearchAttrib.Label)
{
@ -747,11 +830,16 @@
children[0].value = val.age;
else if (attrib == nsMsgSearchAttrib.Date)
children[3].value = convertPRTimeToString(val.date);
else if (attrib == nsMsgSearchAttrib.SenderInAddressBook)
{
var abs = children[4].getElementsByAttribute("value", val.str);
if (abs.length > 0)
children[4].selectedItem = abs[0];
else if (attrib == nsMsgSearchAttrib.Sender)
{
if (this.internalOperator == Components.interfaces.nsMsgSearchOp.IsntInAB ||
this.internalOperator == Components.interfaces.nsMsgSearchOp.IsInAB) {
var abs = children[4].getElementsByAttribute("value", val.str);
if (abs.length > 0)
children[4].selectedItem = abs[0];
}
else
children[0].value = val.str;
}
else if (attrib == nsMsgSearchAttrib.Label)
{
@ -789,8 +877,13 @@
searchValue.age = children[0].value;
else if (searchAttribute == nsMsgSearchAttrib.Date)
searchValue.date = convertStringToPRTime(children[3].value);
else if (searchAttribute == nsMsgSearchAttrib.SenderInAddressBook)
searchValue.str = children[4].selectedItem.value;
else if (searchAttribute == nsMsgSearchAttrib.Sender) {
if (this.internalOperator == Components.interfaces.nsMsgSearchOp.IsntInAB ||
this.internalOperator == Components.interfaces.nsMsgSearchOp.IsInAB)
searchValue.str = children[4].selectedItem.value;
else
searchValue.str = children[0].value;
}
else if (searchAttribute == nsMsgSearchAttrib.Label)
searchValue.label = children[5].selectedItem.value;
else if (searchAttribute == nsMsgSearchAttrib.JunkStatus)

Просмотреть файл

@ -393,18 +393,12 @@ function InitViewBodyMenu()
function IsNewsMessage(messageUri)
{
if (!messageUri)
return false;
else
return (messageUri.substring(0,14) == "news-message:/");
return (/^news-message:/.test(messageUri));
}
function IsImapMessage(messageUri)
{
if (!messageUri)
return false;
else
return (messageUri.substring(0,14) == "imap-message:/");
return (/^imap-message:/.test(messageUri));
}
function SetMenuItemLabel(menuItemId, customLabel)
@ -1893,6 +1887,7 @@ function OnMsgLoaded(folder, msgURI)
var currentMsgFolder = folder.QueryInterface(Components.interfaces.nsIMsgFolder);
if (!IsImapMessage(msgURI))
return;
var imapServer = currentMsgFolder.server.QueryInterface(Components.interfaces.nsIImapIncomingServer);
var storeReadMailInPFC = imapServer.storeReadMailInPFC;
if (storeReadMailInPFC)
@ -1904,16 +1899,7 @@ function OnMsgLoaded(folder, msgURI)
// look in read mail PFC for msg with same msg id - if we find one,
// don't put this message in the read mail pfc.
var outputPFC = imapServer.GetReadMailPFC(true);
var messageURI = GetLoadedMessage();
if (messageURI != msgURI)
{
// XXX TODO
// bienvenu tells me:
// if you have two message windows open, you can get multiple attempts
// to copy into the pfc. the second will fail and assert.
dump("not loading msg into this window - loaded message = " + messageURI + "loading " + msgURI + "\n");
// return;
}
var msgHdr = messenger.messageServiceFromURI(messageURI).messageURIToMsgHdr(messageURI);
if (msgHdr)
{

Просмотреть файл

@ -82,15 +82,12 @@ var folderListener = {
else if (event.GetUnicode() == "DeleteOrMoveMsgFailed") {
HandleDeleteOrMoveMsgFailed(folder);
}
else if (event.GetUnicode() == "msgLoaded") {
OnMsgLoaded(folder, gCurrentMessageUri);
}
}
}
var messagepaneObserver = {
canHandleMultipleItems: false,
canHandleMultipleItems: false,
onDrop: function (aEvent, aData, aDragSession)
{
@ -99,8 +96,7 @@ canHandleMultipleItems: false,
{
var msgHdr = GetMsgHdrFromUri(sourceUri);
var folderUri = msgHdr.folder.URI;
if (folderUri != gCurrentFolderUri)
UpdateDBView(folderUri);
SelectFolder(folderUri);
SelectMessage(sourceUri);
}
},
@ -132,19 +128,6 @@ canHandleMultipleItems: false,
}
};
function UpdateDBView(folderUri)
{
var dbview = GetDBView(); //close old folder view
if (dbview) {
dbview.close();
}
SelectFolder(folderUri);
CreateView(null); //create new folder view
}
function nsMsgDBViewCommandUpdater()
{}
@ -521,8 +504,18 @@ function SetNextMessageAfterDelete()
function SelectFolder(folderUri)
{
gCurrentFolderUri = folderUri;
}
if (folderUri == gCurrentFolderUri)
return;
var dbview = GetDBView(); // close old folder view
if (dbview) {
dbview.close();
}
gCurrentFolderUri = folderUri;
CreateView(null); //create new folder view
}
function GetMsgHdrFromUri(messageUri)
{
@ -905,14 +898,14 @@ var MessageWindowController =
}
};
function performNavigation(type)
function LoadMessageByNavigationType(type)
{
var resultId = new Object;
var resultIndex = new Object;
var threadIndex = new Object;
gDBView.viewNavigate(type, resultId, resultIndex, threadIndex, true /* wrap */);
// if we found something....display it.
if ((resultId.value != nsMsgKey_None) && (resultIndex.value != nsMsgKey_None))
{
@ -920,11 +913,33 @@ function performNavigation(type)
gDBView.loadMessageByMsgKey(resultId.value);
// if we changed folders, the message counts changed.
UpdateStandAloneMessageCounts();
return;
// new message has been loaded
return true;
}
// no message found to load
return false;
}
function performNavigation(type)
{
// Try to load a message by navigation type if we can find
// the message in the same folder.
if (LoadMessageByNavigationType(type))
return;
// we need to span another folder
CrossFolderNavigation(type, false);
var folder = CrossFolderNavigation(type);
if (!folder)
return;
// Try again to load a message by nagivation by type if
// the folder has been changed. If the folder was not changed,
// then the first call to LoadMessageByNavigationType() would
// have loaded the message.
if (folder.Value == gCurrentFolderUri)
LoadMessageByNavigationType(type);
}
function SetupCommandUpdateHandlers()

Просмотреть файл

@ -34,10 +34,6 @@
var msgHeaderParserContractID = "@mozilla.org/messenger/headerparser;1";
var abAddressCollectorContractID = "@mozilla.org/addressbook/services/addressCollecter;1";
// get the "msgLoad" atom
var atomService = Components.classes["@mozilla.org/atom-service;1"].getService().QueryInterface(Components.interfaces.nsIAtomService);
var gMsgLoadedAtom = atomService.getAtom("msgLoaded").QueryInterface(Components.interfaces.nsISupports);
var gViewAllHeaders = false;
var gNumAddressesToShow = 3;
var gShowUserAgent = false;
@ -297,7 +293,7 @@ var messageHeaderSink = {
{
this.onStartHeaders();
var index = 0;
var index = 0;
// process each header
while (index < numHeaders)
{
@ -309,11 +305,19 @@ var messageHeaderSink = {
foo.headerValue = headerValues[index];
foo.headerName = headerNames[index];
// some times, you can have multiple To or cc lines....in this case, we want to APPEND
// these headers into one.
if ( (lowerCaseHeaderName == 'to' || lowerCaseHeaderName == 'cc') && ( lowerCaseHeaderName in currentHeaderData))
// according to RFC 2822, certain headers
// can occur "unlimited" times
if (lowerCaseHeaderName in currentHeaderData)
{
currentHeaderData[lowerCaseHeaderName].headerValue = currentHeaderData[lowerCaseHeaderName].headerValue + ',' + foo.headerValue;
// sometimes, you can have multiple To or Cc lines....
// in this case, we want to append these headers into one.
if (lowerCaseHeaderName == 'to' || lowerCaseHeaderName == 'cc')
currentHeaderData[lowerCaseHeaderName].headerValue = currentHeaderData[lowerCaseHeaderName].headerValue + ',' + foo.headerValue;
else {
// use the index to create a unique header name like:
// received5, received6, etc
currentHeaderData[lowerCaseHeaderName + index] = foo;
}
}
else
currentHeaderData[lowerCaseHeaderName] = foo;
@ -374,12 +378,12 @@ var messageHeaderSink = {
onEndMsgDownload: function(url)
{
var msgFolder;
if (url)
{
msgFolder = url.folder;
if (msgFolder)
msgFolder.NotifyFolderEvent(gMsgLoadedAtom);
var msgFolder = url.folder;
var msgURI = GetLoadedMessage();
if (msgFolder && msgURI)
OnMsgLoaded(msgFolder, msgURI);
}
},

Просмотреть файл

@ -255,9 +255,6 @@ var folderListener = {
else if(eventType == "RenameCompleted") {
SelectFolder(folder.URI);
}
else if (eventType == "msgLoaded") {
OnMsgLoaded(folder, gDBView.URIForFirstSelectedMessage);
}
}
}

Просмотреть файл

@ -193,7 +193,7 @@ function GetRootFoldersInFolderPaneOrder()
return serversMsgFolders;
}
function CrossFolderNavigation(type, supportsFolderPane )
function CrossFolderNavigation(type)
{
if (type != nsMsgNavigationType.nextUnreadMessage) {
// only do cross folder navigation for "next unread message"
@ -214,16 +214,14 @@ function CrossFolderNavigation(type, supportsFolderPane )
case 0:
// do this unconditionally
gNextMessageAfterLoad = type;
if (supportsFolderPane)
SelectFolder(folder.URI);
SelectFolder(folder.URI);
break;
case 1:
default:
var promptText = gMessengerBundle.getFormattedString("advanceNextPrompt", [ folder.name ], 1);
if (promptService.confirm(window, promptText, promptText)) {
gNextMessageAfterLoad = type;
if (supportsFolderPane)
SelectFolder(folder.URI);
SelectFolder(folder.URI);
}
break;
}
@ -268,7 +266,7 @@ function GoNextMessage(type, startFromBeginning)
try {
var succeeded = ScrollToMessage(type, startFromBeginning, true);
if (!succeeded) {
CrossFolderNavigation(type, true);
CrossFolderNavigation(type);
}
}
catch (ex) {

Просмотреть файл

@ -102,10 +102,9 @@ interface nsMsgSearchAttrib {
const nsMsgSearchAttribValue Department = 30;
const nsMsgSearchAttribValue AdditionalEmail = 31;
// 32 - 45, reserved for ab / LDAP;
// 32 - 46, reserved for ab / LDAP;
const nsMsgSearchAttribValue JunkStatus = 46;
const nsMsgSearchAttribValue SenderInAddressBook = 47;
const nsMsgSearchAttribValue JunkStatus = 47;
const nsMsgSearchAttribValue Label = 48; /* mail only...can search by label */
//49 is for showing customize... in ui headers start from 50 onwards up until 99.
const nsMsgSearchAttribValue OtherHeader = 49; /* for mail and news. MUST ALWAYS BE LAST attribute since we can have an arbitrary # of these... */

Просмотреть файл

@ -181,7 +181,6 @@ var gFolderListener = {
else if (eventType == "DeleteOrMoveMsgFailed") {
HandleDeleteOrMoveMessageFailed(folder);
}
}
}

Просмотреть файл

@ -306,6 +306,7 @@ function createSearchRow(index, scope, searchTerm)
enclosingBox.appendChild(boolOp);
searchAttr.setAttribute("for", searchOp.id + "," + searchVal.id);
searchOp.setAttribute("opfor", searchVal.id);
var rowdata = new Array(enclosingBox, searchAttr,
null, searchOp,

Просмотреть файл

@ -54,15 +54,15 @@
<listitem id="searchListItem">
<listcell id="preSearchAttr"/>
<listcell allowevents="true">
<searchattribute id="searchAttr" for="searchOp,searchValue" flex="1"/>
<searchattribute id="searchAttr1" for="searchOp1,searchValue1" flex="1"/>
</listcell>
<listcell id="preSearchOp"/>
<listcell allowevents="true">
<searchoperator id="searchOp" flex="1"/>
<searchoperator id="searchOp1" opfor="searchValue1" flex="1"/>
</listcell>
<listcell id="preSearchValue"/>
<listcell allowevents="true" >
<searchvalue id="searchValue" flex="1"/>
<searchvalue id="searchValue1" flex="1"/>
</listcell>
<listcell id="postSearchValue"/>
</listitem>

Просмотреть файл

@ -47,8 +47,8 @@
43=reserved for AB
44=reserved for AB
45=reserved for AB
46=Junk Status
47=Sender
46=reserved for AB
47=Junk Status
48=Label
# don't use above 49
49=Customize...

Просмотреть файл

@ -193,10 +193,10 @@ nsresult nsMsgSearchValidityManager::InitOfflineMailTable ()
m_offlineMailTable->SetAvailable (nsMsgSearchAttrib::Sender, nsMsgSearchOp::EndsWith, 1);
m_offlineMailTable->SetEnabled (nsMsgSearchAttrib::Sender, nsMsgSearchOp::EndsWith, 1);
m_offlineMailTable->SetAvailable (nsMsgSearchAttrib::SenderInAddressBook, nsMsgSearchOp::IsInAB, 1);
m_offlineMailTable->SetEnabled (nsMsgSearchAttrib::SenderInAddressBook, nsMsgSearchOp::IsInAB, 1);
m_offlineMailTable->SetAvailable (nsMsgSearchAttrib::SenderInAddressBook, nsMsgSearchOp::IsntInAB, 1);
m_offlineMailTable->SetEnabled (nsMsgSearchAttrib::SenderInAddressBook, nsMsgSearchOp::IsntInAB, 1);
m_offlineMailTable->SetAvailable (nsMsgSearchAttrib::Sender, nsMsgSearchOp::IsInAB, 1);
m_offlineMailTable->SetEnabled (nsMsgSearchAttrib::Sender, nsMsgSearchOp::IsInAB, 1);
m_offlineMailTable->SetAvailable (nsMsgSearchAttrib::Sender, nsMsgSearchOp::IsntInAB, 1);
m_offlineMailTable->SetEnabled (nsMsgSearchAttrib::Sender, nsMsgSearchOp::IsntInAB, 1);
m_offlineMailTable->SetAvailable (nsMsgSearchAttrib::Label, nsMsgSearchOp::Is, 1);
m_offlineMailTable->SetEnabled (nsMsgSearchAttrib::Label, nsMsgSearchOp::Is, 1);
@ -414,10 +414,10 @@ nsresult nsMsgSearchValidityManager::InitOnlineMailFilterTable()
m_onlineMailFilterTable->SetAvailable (nsMsgSearchAttrib::Sender, nsMsgSearchOp::EndsWith, 1);
m_onlineMailFilterTable->SetEnabled (nsMsgSearchAttrib::Sender, nsMsgSearchOp::EndsWith, 1);
m_onlineMailFilterTable->SetAvailable (nsMsgSearchAttrib::SenderInAddressBook, nsMsgSearchOp::IsInAB, 1);
m_onlineMailFilterTable->SetEnabled (nsMsgSearchAttrib::SenderInAddressBook, nsMsgSearchOp::IsInAB, 1);
m_onlineMailFilterTable->SetAvailable (nsMsgSearchAttrib::SenderInAddressBook, nsMsgSearchOp::IsntInAB, 1);
m_onlineMailFilterTable->SetEnabled (nsMsgSearchAttrib::SenderInAddressBook, nsMsgSearchOp::IsntInAB, 1);
m_onlineMailFilterTable->SetAvailable (nsMsgSearchAttrib::Sender, nsMsgSearchOp::IsInAB, 1);
m_onlineMailFilterTable->SetEnabled (nsMsgSearchAttrib::Sender, nsMsgSearchOp::IsInAB, 1);
m_onlineMailFilterTable->SetAvailable (nsMsgSearchAttrib::Sender, nsMsgSearchOp::IsntInAB, 1);
m_onlineMailFilterTable->SetEnabled (nsMsgSearchAttrib::Sender, nsMsgSearchOp::IsntInAB, 1);
m_onlineMailFilterTable->SetAvailable (nsMsgSearchAttrib::To, nsMsgSearchOp::Contains, 1);
m_onlineMailFilterTable->SetEnabled (nsMsgSearchAttrib::To, nsMsgSearchOp::Contains, 1);

Просмотреть файл

@ -492,7 +492,6 @@ nsresult nsMsgSearchOfflineMail::ProcessSearchTerm(nsIMsgDBHdr *msgToMatch,
switch (attrib)
{
case nsMsgSearchAttrib::SenderInAddressBook:
case nsMsgSearchAttrib::Sender:
msgToMatch->GetAuthor(getter_Copies(matchString));
err = aTerm->MatchRfc822String (matchString, charset, charsetOverride, &result);

Просмотреть файл

@ -740,10 +740,10 @@ nsresult nsMsgSearchValidityManager::InitNewsFilterTable()
m_newsFilterTable->SetAvailable (nsMsgSearchAttrib::Sender, nsMsgSearchOp::EndsWith, 1);
m_newsFilterTable->SetEnabled (nsMsgSearchAttrib::Sender, nsMsgSearchOp::EndsWith, 1);
m_newsFilterTable->SetAvailable (nsMsgSearchAttrib::SenderInAddressBook, nsMsgSearchOp::IsInAB, 1);
m_newsFilterTable->SetEnabled (nsMsgSearchAttrib::SenderInAddressBook, nsMsgSearchOp::IsInAB, 1);
m_newsFilterTable->SetAvailable (nsMsgSearchAttrib::SenderInAddressBook, nsMsgSearchOp::IsntInAB, 1);
m_newsFilterTable->SetEnabled (nsMsgSearchAttrib::SenderInAddressBook, nsMsgSearchOp::IsntInAB, 1);
m_newsFilterTable->SetAvailable (nsMsgSearchAttrib::Sender, nsMsgSearchOp::IsInAB, 1);
m_newsFilterTable->SetEnabled (nsMsgSearchAttrib::Sender, nsMsgSearchOp::IsInAB, 1);
m_newsFilterTable->SetAvailable (nsMsgSearchAttrib::Sender, nsMsgSearchOp::IsntInAB, 1);
m_newsFilterTable->SetEnabled (nsMsgSearchAttrib::Sender, nsMsgSearchOp::IsntInAB, 1);
m_newsFilterTable->SetAvailable (nsMsgSearchAttrib::Subject, nsMsgSearchOp::Contains, 1);
m_newsFilterTable->SetEnabled (nsMsgSearchAttrib::Subject, nsMsgSearchOp::Contains, 1);

Просмотреть файл

@ -82,19 +82,23 @@ typedef struct
nsMsgSearchAttribEntry SearchAttribEntryTable[] =
{
{nsMsgSearchAttrib::Subject, "subject"},
{nsMsgSearchAttrib::Sender, "from"},
{nsMsgSearchAttrib::Body, "body"},
{nsMsgSearchAttrib::Date, "date"},
{nsMsgSearchAttrib::Priority, "priority"},
{nsMsgSearchAttrib::MsgStatus, "status"},
{nsMsgSearchAttrib::To, "to"},
{nsMsgSearchAttrib::CC, "cc"},
{nsMsgSearchAttrib::ToOrCC, "to or cc"},
{nsMsgSearchAttrib::AgeInDays, "age in days"},
{nsMsgSearchAttrib::Label, "label"},
{nsMsgSearchAttrib::SenderInAddressBook, "from in ab"},
{nsMsgSearchAttrib::JunkStatus, "junk status"},
{nsMsgSearchAttrib::Subject, "subject"},
{nsMsgSearchAttrib::Sender, "from"},
{nsMsgSearchAttrib::Body, "body"},
{nsMsgSearchAttrib::Date, "date"},
{nsMsgSearchAttrib::Priority, "priority"},
{nsMsgSearchAttrib::MsgStatus, "status"},
{nsMsgSearchAttrib::To, "to"},
{nsMsgSearchAttrib::CC, "cc"},
{nsMsgSearchAttrib::ToOrCC, "to or cc"},
{nsMsgSearchAttrib::AgeInDays, "age in days"},
{nsMsgSearchAttrib::Label, "label"},
// this used to be nsMsgSearchAttrib::SenderInAddressBook
// we used to have two Sender menuitems
// for backward compatability, we can still parse
// the old style. see bug #179803
{nsMsgSearchAttrib::Sender, "from in ab"},
{nsMsgSearchAttrib::JunkStatus, "junk status"},
};
// Take a string which starts off with an attribute
@ -570,40 +574,34 @@ nsMsgSearchTerm::ParseOperator(char *inStream, nsMsgSearchOpValue *value)
// find the attribute code for this comma-delimited attribute.
nsresult
nsMsgSearchTerm::ParseAttribute(char *inStream, nsMsgSearchAttribValue *attrib)
{
nsCAutoString attributeStr;
PRInt16 attributeVal;
nsresult err;
{
while (nsString::IsSpace(*inStream))
inStream++;
// if we are dealing with an arbitrary header, it may be quoted....
PRBool quoteVal = PR_FALSE;
if (*inStream == '"')
{
quoteVal = PR_TRUE;
inStream++;
}
// arbitrary headers are quoted
char *separator = strchr(inStream, quoteVal ? '"' : ',');
while (nsString::IsSpace(*inStream))
inStream++;
// if we are dealing with an arbitrary header, it may be quoted....
PRBool quoteVal = PR_FALSE;
if (*inStream == '"')
{
quoteVal = PR_TRUE;
inStream++;
}
char *separator;
if (quoteVal) // arbitrary headers are quoted...
separator = PL_strchr(inStream, '"');
else
separator = PL_strchr(inStream, ',');
if (separator)
*separator = '\0';
err = NS_MsgGetAttributeFromString(inStream, &attributeVal);
NS_ENSURE_SUCCESS(err, err);
*attrib = (nsMsgSearchAttribValue) attributeVal;
if (*attrib > nsMsgSearchAttrib::OtherHeader && *attrib < nsMsgSearchAttrib::kNumMsgSearchAttributes) // if we are dealing with an arbitrary header....
m_arbitraryHeader = inStream;
return err;
if (separator)
*separator = '\0';
PRInt16 attributeVal;
nsresult rv = NS_MsgGetAttributeFromString(inStream, &attributeVal);
NS_ENSURE_SUCCESS(rv, rv);
*attrib = (nsMsgSearchAttribValue) attributeVal;
if (*attrib > nsMsgSearchAttrib::OtherHeader && *attrib < nsMsgSearchAttrib::kNumMsgSearchAttributes) // if we are dealing with an arbitrary header....
m_arbitraryHeader = inStream;
return rv;
}
// De stream one search term. If the condition looks like
@ -854,7 +852,7 @@ nsresult nsMsgSearchTerm::InitializeAddressBook()
nsXPIDLCString dirURI;
mDirectory->GetDirUri(getter_Copies(dirURI));
if (strcmp(dirURI.get(), m_value.string))
mDirectory = NULL; // clear out the directory....we are no longer pointing to the right one
mDirectory = nsnull; // clear out the directory....we are no longer pointing to the right one
}
if (!mDirectory)
{
@ -904,7 +902,9 @@ nsresult nsMsgSearchTerm::MatchRfc2047String (const char *rfc2047string,
charset, charsetOverride,
PR_FALSE);
if (nsMsgSearchAttrib::SenderInAddressBook == m_attribute)
if (m_attribute == nsMsgSearchAttrib::Sender &&
(m_operator == nsMsgSearchOp::IsInAB ||
m_operator == nsMsgSearchOp::IsntInAB))
{
res = MatchInAddressBook(stringToMatch ? stringToMatch : rfc2047string, pResult);
}
@ -1067,7 +1067,9 @@ nsresult nsMsgSearchTerm::MatchRfc822String (const char *string, const char *cha
{
walkNames = names + namePos;
walkAddresses = addresses + addressPos;
if (nsMsgSearchAttrib::SenderInAddressBook == m_attribute)
if (m_attribute == nsMsgSearchAttrib::Sender &&
(m_operator == nsMsgSearchOp::IsInAB ||
m_operator == nsMsgSearchOp::IsntInAB))
{
err = MatchRfc2047String (walkAddresses.get(), charset, charsetOverride, &result);
}

Просмотреть файл

@ -3,7 +3,7 @@ logging="no"
name="People I Know"
enabled="yes"
type="1"
condition="AND (from in ab,is in ab,moz-abmdbdirectory://abook.mab)"
condition="AND (from,is in ab,moz-abmdbdirectory://abook.mab)"
name="Recent Mail"
enabled="yes"
type="1"