зеркало из https://github.com/mozilla/pjs.git
change add/remove keyword to take handle multiple keywords, so that remove all will work, sr=mscott 367011
This commit is contained in:
Родитель
2cbac531d0
Коммит
750636642a
|
@ -493,24 +493,44 @@ function RemoveAllMessageTags()
|
|||
var selectedMsgUris = GetSelectedMessages();
|
||||
if (!selectedMsgUris.length)
|
||||
return;
|
||||
|
||||
var msg = Components.classes["@mozilla.org/supports-array;1"]
|
||||
.createInstance(Components.interfaces.nsISupportsArray);
|
||||
|
||||
|
||||
var messages = Components.classes["@mozilla.org/supports-array;1"]
|
||||
.createInstance(Components.interfaces.nsISupportsArray);
|
||||
var tagService = Components.classes["@mozilla.org/messenger/tagservice;1"]
|
||||
.getService(Components.interfaces.nsIMsgTagService);
|
||||
var tagArray = tagService.getAllTags({});
|
||||
|
||||
var allKeys = "";
|
||||
for (j = 0; j < tagArray.length; ++j)
|
||||
{
|
||||
if (j)
|
||||
allKeys += " ";
|
||||
allKeys += tagArray[j].key;
|
||||
}
|
||||
|
||||
var prevHdrFolder = null;
|
||||
// this crudely handles cross-folder virtual folders with selected messages
|
||||
// that spans folders, by coalescing consecutive messages in the selection
|
||||
// that happen to be in the same folder. nsMsgSearchDBView does this better,
|
||||
// but nsIMsgDBView doesn't handle commands with arguments, and untag takes a
|
||||
// key argument. Furthermore, we only delete legacy labels and known tags,
|
||||
// keeping other keywords like (non)junk intact.
|
||||
var j;
|
||||
for (var i = 0; i < selectedMsgUris.length; ++i)
|
||||
{
|
||||
// remove all tags by removing all their tag keys, all at once.
|
||||
// (using a msgHdr's setStringProperty won't notify the threadPane!)
|
||||
var msgHdr = messenger.msgHdrFromURI(selectedMsgUris[i]);
|
||||
msgHdr.label = 0; // remove legacy label
|
||||
msg.Clear();
|
||||
msg.AppendElement(msgHdr);
|
||||
|
||||
var keywords = msgHdr.getStringProperty("keywords");
|
||||
// this will remove all keywords at once...
|
||||
if (keywords.length > 0)
|
||||
msgHdr.folder.removeKeywordFromMessages(msg, keywords);
|
||||
if (prevHdrFolder != msgHdr.folder)
|
||||
{
|
||||
if (prevHdrFolder)
|
||||
prevHdrFolder.removeKeywordsFromMessages(messages, allKeys);
|
||||
messages.Clear();
|
||||
prevHdrFolder = msgHdr.folder;
|
||||
}
|
||||
messages.AppendElement(msgHdr);
|
||||
}
|
||||
if (prevHdrFolder)
|
||||
prevHdrFolder.removeKeywordsFromMessages(messages, allKeys);
|
||||
OnTagsChange();
|
||||
}
|
||||
|
||||
|
@ -554,7 +574,7 @@ function ToggleMessageTag(key, addKey)
|
|||
var msg = Components.classes["@mozilla.org/supports-array;1"]
|
||||
.createInstance(Components.interfaces.nsISupportsArray);
|
||||
var selectedMsgUris = GetSelectedMessages();
|
||||
var toggler = addKey ? "addKeywordToMessages" : "removeKeywordFromMessages";
|
||||
var toggler = addKey ? "addKeywordsToMessages" : "removeKeywordsFromMessages";
|
||||
var prevHdrFolder = null;
|
||||
// this crudely handles cross-folder virtual folders with selected messages
|
||||
// that spans folders, by coalescing consecutive msgs in the selection
|
||||
|
@ -571,7 +591,7 @@ function ToggleMessageTag(key, addKey)
|
|||
// because resetting a label doesn't update the tree anymore...
|
||||
msg.Clear();
|
||||
msg.AppendElement(msgHdr);
|
||||
msgHdr.folder.addKeywordToMessages(msg, "$label" + msgHdr.label);
|
||||
msgHdr.folder.addKeywordsToMessages(msg, "$label" + msgHdr.label);
|
||||
msgHdr.label = 0; // remove legacy label
|
||||
}
|
||||
if (prevHdrFolder != msgHdr.folder)
|
||||
|
|
|
@ -71,7 +71,7 @@ typedef long nsMsgBiffState;
|
|||
// enumerated type for determining if a message has been replied to, forwarded, etc.
|
||||
typedef long nsMsgDispositionState;
|
||||
|
||||
[scriptable, uuid(913D683A-206F-4c91-9B10-3FC4CAEA644E)]
|
||||
[scriptable, uuid(83d2454c-632e-4d6e-900a-7236a6d2aa9a)]
|
||||
interface nsIMsgFolder : nsICollection {
|
||||
|
||||
const nsMsgBiffState nsMsgBiffState_NewMail = 0; // User has new mail waiting.
|
||||
|
@ -495,9 +495,9 @@ const nsMsgBiffState nsMsgBiffState_Unknown = 2; // We dunno whether there is ne
|
|||
|
||||
// used to set/clear tags - we could have a single method to setKeywords which
|
||||
// would figure out the diffs, but these methods might be more convenient.
|
||||
void addKeywordToMessages(in nsISupportsArray aMessages, in string aKeyword);
|
||||
void removeKeywordFromMessages(in nsISupportsArray aMessages, in string aKeyword);
|
||||
|
||||
// keywords are space delimited, in the case of multiple keywords
|
||||
void addKeywordsToMessages(in nsISupportsArray aMessages, in string aKeywords);
|
||||
void removeKeywordsFromMessages(in nsISupportsArray aMessages, in string aKeywords);
|
||||
/**
|
||||
* Extract the message preview text from aStream, storing it as a string property
|
||||
* on aMsgHdr.
|
||||
|
|
|
@ -473,16 +473,44 @@ function RemoveAllMessageTags()
|
|||
var selectedMsgUris = GetSelectedMessages();
|
||||
if (!selectedMsgUris.length)
|
||||
return;
|
||||
|
||||
|
||||
var messages = Components.classes["@mozilla.org/supports-array;1"]
|
||||
.createInstance(Components.interfaces.nsISupportsArray);
|
||||
var tagService = Components.classes["@mozilla.org/messenger/tagservice;1"]
|
||||
.getService(Components.interfaces.nsIMsgTagService);
|
||||
var tagArray = tagService.getAllTags({});
|
||||
|
||||
var allKeys = "";
|
||||
for (j = 0; j < tagArray.length; ++j)
|
||||
{
|
||||
if (j)
|
||||
allKeys += " ";
|
||||
allKeys += tagArray[j].key;
|
||||
}
|
||||
|
||||
var prevHdrFolder = null;
|
||||
// this crudely handles cross-folder virtual folders with selected messages
|
||||
// that spans folders, by coalescing consecutive messages in the selection
|
||||
// that happen to be in the same folder. nsMsgSearchDBView does this better,
|
||||
// but nsIMsgDBView doesn't handle commands with arguments, and untag takes a
|
||||
// key argument. Furthermore, we only delete legacy labels and known tags,
|
||||
// keeping other keywords like (non)junk intact.
|
||||
var j;
|
||||
for (var i = 0; i < selectedMsgUris.length; ++i)
|
||||
{
|
||||
// remove all tags by removing all their tag keys at once
|
||||
// (using a msgHdr's setStringProperty won't notify the threadPane!)
|
||||
var msgHdr = messenger.msgHdrFromURI(selectedMsgUris[i]);
|
||||
msgHdr.label = 0; // remove legacy label
|
||||
msgHdr.folder.getMsgDatabase(msgWindow)
|
||||
.setStringProperty(msgHdr.messageKey, "keywords", "");
|
||||
if (prevHdrFolder != msgHdr.folder)
|
||||
{
|
||||
if (prevHdrFolder)
|
||||
prevHdrFolder.removeKeywordsFromMessages(messages, allKeys);
|
||||
messages.Clear();
|
||||
prevHdrFolder = msgHdr.folder;
|
||||
}
|
||||
messages.AppendElement(msgHdr);
|
||||
}
|
||||
if (prevHdrFolder)
|
||||
prevHdrFolder.removeKeywordsFromMessages(messages, allKeys);
|
||||
OnTagsChange();
|
||||
}
|
||||
|
||||
|
@ -547,7 +575,7 @@ function ToggleMessageTag(key, addKey)
|
|||
var msg = Components.classes["@mozilla.org/supports-array;1"]
|
||||
.createInstance(Components.interfaces.nsISupportsArray);
|
||||
var selectedMsgUris = GetSelectedMessages();
|
||||
var toggler = addKey ? "addKeywordToMessages" : "removeKeywordFromMessages";
|
||||
var toggler = addKey ? "addKeywordsToMessages" : "removeKeywordsFromMessages";
|
||||
var prevHdrFolder = null;
|
||||
// this crudely handles cross-folder virtual folders with selected messages
|
||||
// that spans folders, by coalescing consecutive msgs in the selection
|
||||
|
@ -564,7 +592,7 @@ function ToggleMessageTag(key, addKey)
|
|||
// because resetting a label doesn't update the tree anymore...
|
||||
msg.Clear();
|
||||
msg.AppendElement(msgHdr);
|
||||
msgHdr.folder.addKeywordToMessages(msg, "$label" + msgHdr.label);
|
||||
msgHdr.folder.addKeywordsToMessages(msg, "$label" + msgHdr.label);
|
||||
msgHdr.label = 0; // remove legacy label
|
||||
}
|
||||
if (prevHdrFolder != msgHdr.folder)
|
||||
|
|
|
@ -651,7 +651,7 @@ nsresult nsMsgFilterAfterTheFact::ApplyFilter()
|
|||
{
|
||||
nsXPIDLCString keyword;
|
||||
filterAction->GetStrValue(getter_Copies(keyword));
|
||||
m_curFolder->AddKeywordToMessages(m_searchHitHdrs, keyword.get());
|
||||
m_curFolder->AddKeywordsToMessages(m_searchHitHdrs, keyword.get());
|
||||
}
|
||||
break;
|
||||
case nsMsgFilterAction::JunkScore:
|
||||
|
|
|
@ -5469,7 +5469,7 @@ void nsMsgDBFolder::SetMRUTime()
|
|||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsMsgDBFolder::AddKeywordToMessages(nsISupportsArray *aMessages, const char *aKeyword)
|
||||
NS_IMETHODIMP nsMsgDBFolder::AddKeywordsToMessages(nsISupportsArray *aMessages, const char *aKeywords)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
GetDatabase(nsnull);
|
||||
|
@ -5489,20 +5489,25 @@ NS_IMETHODIMP nsMsgDBFolder::AddKeywordToMessages(nsISupportsArray *aMessages, c
|
|||
(void) message->GetMessageKey(&msgKey);
|
||||
|
||||
message->GetStringProperty("keywords", getter_Copies(keywords));
|
||||
nsACString::const_iterator start, end;
|
||||
if (!MsgFindKeyword(nsDependentCString(aKeyword), keywords, start, end))
|
||||
nsCStringArray keywordArray;
|
||||
keywordArray.ParseString(aKeywords, " ");
|
||||
for (PRInt32 j = 0; j < keywordArray.Count(); j++)
|
||||
{
|
||||
if (!keywords.IsEmpty())
|
||||
keywords.Append(' ');
|
||||
keywords.Append(aKeyword);
|
||||
mDatabase->SetStringProperty(msgKey, "keywords", keywords);
|
||||
nsACString::const_iterator start, end;
|
||||
if (!MsgFindKeyword(*(keywordArray[j]), keywords, start, end))
|
||||
{
|
||||
if (!keywords.IsEmpty())
|
||||
keywords.Append(' ');
|
||||
keywords.Append(keywordArray[j]->get());
|
||||
}
|
||||
}
|
||||
mDatabase->SetStringProperty(msgKey, "keywords", keywords);
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgDBFolder::RemoveKeywordFromMessages(nsISupportsArray *aMessages, const char *aKeyword)
|
||||
NS_IMETHODIMP nsMsgDBFolder::RemoveKeywordsFromMessages(nsISupportsArray *aMessages, const char *aKeywords)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
GetDatabase(nsnull);
|
||||
|
@ -5514,7 +5519,6 @@ NS_IMETHODIMP nsMsgDBFolder::RemoveKeywordFromMessages(nsISupportsArray *aMessag
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsXPIDLCString keywords;
|
||||
// If the tag is also a label, we should remove the label too...
|
||||
PRBool keywordIsLabel = (!PL_strncasecmp(aKeyword, "$label", 6) && aKeyword[6] >= '1' && aKeyword[6] <= '5');
|
||||
|
||||
for(PRUint32 i = 0; i < count; i++)
|
||||
{
|
||||
|
@ -5522,31 +5526,38 @@ NS_IMETHODIMP nsMsgDBFolder::RemoveKeywordFromMessages(nsISupportsArray *aMessag
|
|||
nsCOMPtr<nsIMsgDBHdr> message = do_QueryElementAt(aMessages, i, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
(void) message->GetMessageKey(&msgKey);
|
||||
if (keywordIsLabel)
|
||||
{
|
||||
nsMsgLabelValue labelValue;
|
||||
message->GetLabel(&labelValue);
|
||||
// if we're removing the keyword that corresponds to a pre 2.0 label,
|
||||
// we need to clear the old label attribute on the messsage.
|
||||
if (labelValue == (nsMsgLabelValue) (aKeyword[6] - '0'))
|
||||
message->SetLabel((nsMsgLabelValue) 0);
|
||||
}
|
||||
|
||||
rv = message->GetStringProperty("keywords", getter_Copies(keywords));
|
||||
nsACString::const_iterator start, end;
|
||||
nsACString::const_iterator saveStart;
|
||||
keywords.BeginReading(saveStart);
|
||||
if (MsgFindKeyword(nsDependentCString(aKeyword), keywords, start, end))
|
||||
nsCStringArray keywordArray;
|
||||
keywordArray.ParseString(aKeywords, " ");
|
||||
for (PRInt32 j = 0; j < keywordArray.Count(); j++)
|
||||
{
|
||||
keywords.Cut(Distance(saveStart, start), Distance(start, end));
|
||||
mDatabase->SetStringProperty(msgKey, "keywords", keywords);
|
||||
PRBool keywordIsLabel = (StringBeginsWith(*(keywordArray[j]), NS_LITERAL_CSTRING("$label"))
|
||||
&& keywordArray[j]->CharAt(6) >= '1' && keywordArray[j]->CharAt(6) <= '5');
|
||||
if (keywordIsLabel)
|
||||
{
|
||||
nsMsgLabelValue labelValue;
|
||||
message->GetLabel(&labelValue);
|
||||
// if we're removing the keyword that corresponds to a pre 2.0 label,
|
||||
// we need to clear the old label attribute on the messsage.
|
||||
if (labelValue == (nsMsgLabelValue) (keywordArray[j]->CharAt(6) - '0'))
|
||||
message->SetLabel((nsMsgLabelValue) 0);
|
||||
}
|
||||
|
||||
nsACString::const_iterator start, end;
|
||||
nsACString::const_iterator saveStart;
|
||||
keywords.BeginReading(saveStart);
|
||||
if (MsgFindKeyword(*(keywordArray[j]), keywords, start, end))
|
||||
{
|
||||
keywords.Cut(Distance(saveStart, start), Distance(start, end));
|
||||
NS_ASSERTION(keywords.IsEmpty() || keywords.CharAt(0) != ' ', "space only keyword");
|
||||
}
|
||||
}
|
||||
mDatabase->SetStringProperty(msgKey, "keywords", keywords);
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsMsgDBFolder::GetCustomIdentity(nsIMsgIdentity **aIdentity)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aIdentity);
|
||||
|
|
|
@ -3478,7 +3478,7 @@ NS_IMETHODIMP nsImapMailFolder::ApplyFilterHit(nsIMsgFilter *filter, nsIMsgWindo
|
|||
nsCOMPtr<nsISupportsArray> messageArray;
|
||||
NS_NewISupportsArray(getter_AddRefs(messageArray));
|
||||
messageArray->AppendElement(msgHdr);
|
||||
AddKeywordToMessages(messageArray, keyword.get());
|
||||
AddKeywordsToMessages(messageArray, keyword.get());
|
||||
break;
|
||||
}
|
||||
case nsMsgFilterAction::JunkScore:
|
||||
|
@ -8601,32 +8601,32 @@ NS_IMETHODIMP nsImapMailFolder::FetchMsgPreviewText(nsMsgKey *aKeysToFetch, PRUi
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImapMailFolder::AddKeywordToMessages(nsISupportsArray *aMessages, const char *aKeyword)
|
||||
NS_IMETHODIMP nsImapMailFolder::AddKeywordsToMessages(nsISupportsArray *aMessages, const char *aKeywords)
|
||||
{
|
||||
nsresult rv = nsMsgDBFolder::AddKeywordToMessages(aMessages, aKeyword);
|
||||
nsresult rv = nsMsgDBFolder::AddKeywordsToMessages(aMessages, aKeywords);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
nsCAutoString messageIds;
|
||||
nsMsgKeyArray keys;
|
||||
rv = BuildIdsAndKeyArray(aMessages, messageIds, keys);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = StoreCustomKeywords(nsnull, aKeyword, nsnull, keys.GetArray(), keys.GetSize(), nsnull);
|
||||
rv = StoreCustomKeywords(nsnull, aKeywords, nsnull, keys.GetArray(), keys.GetSize(), nsnull);
|
||||
if (mDatabase)
|
||||
mDatabase->Commit(nsMsgDBCommitType::kLargeCommit);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImapMailFolder::RemoveKeywordFromMessages(nsISupportsArray *aMessages, const char *aKeyword)
|
||||
NS_IMETHODIMP nsImapMailFolder::RemoveKeywordsFromMessages(nsISupportsArray *aMessages, const char *aKeywords)
|
||||
{
|
||||
nsresult rv = nsMsgDBFolder::RemoveKeywordFromMessages(aMessages, aKeyword);
|
||||
nsresult rv = nsMsgDBFolder::RemoveKeywordsFromMessages(aMessages, aKeywords);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
nsCAutoString messageIds;
|
||||
nsMsgKeyArray keys;
|
||||
nsresult rv = BuildIdsAndKeyArray(aMessages, messageIds, keys);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = StoreCustomKeywords(nsnull, nsnull, aKeyword, keys.GetArray(), keys.GetSize(), nsnull);
|
||||
rv = StoreCustomKeywords(nsnull, nsnull, aKeywords, keys.GetArray(), keys.GetSize(), nsnull);
|
||||
if (mDatabase)
|
||||
mDatabase->Commit(nsMsgDBCommitType::kLargeCommit);
|
||||
}
|
||||
|
|
|
@ -294,8 +294,8 @@ public:
|
|||
PRBool aLocalOnly, nsIUrlListener *aUrlListener,
|
||||
PRBool *aAsyncResults);
|
||||
|
||||
NS_IMETHOD AddKeywordToMessages(nsISupportsArray *aMessages, const char *aKeyword);
|
||||
NS_IMETHOD RemoveKeywordFromMessages(nsISupportsArray *aMessages, const char *aKeyword);
|
||||
NS_IMETHOD AddKeywordsToMessages(nsISupportsArray *aMessages, const char *aKeywords);
|
||||
NS_IMETHOD RemoveKeywordsFromMessages(nsISupportsArray *aMessages, const char *aKeywords);
|
||||
|
||||
// nsIMsgImapMailFolder methods
|
||||
NS_DECL_NSIMSGIMAPMAILFOLDER
|
||||
|
|
|
@ -3921,14 +3921,14 @@ NS_IMETHODIMP nsMsgLocalMailFolder::FetchMsgPreviewText(nsMsgKey *aKeysToFetch,
|
|||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgLocalMailFolder::AddKeywordToMessages(nsISupportsArray *aMessages, const char *aKeyword)
|
||||
NS_IMETHODIMP nsMsgLocalMailFolder::AddKeywordsToMessages(nsISupportsArray *aMessages, const char *aKeywords)
|
||||
{
|
||||
return ChangeKeywordForMessages(aMessages, aKeyword, PR_TRUE /* add */);
|
||||
return ChangeKeywordForMessages(aMessages, aKeywords, PR_TRUE /* add */);
|
||||
}
|
||||
nsresult nsMsgLocalMailFolder::ChangeKeywordForMessages(nsISupportsArray *aMessages, const char *aKeyword, PRBool add)
|
||||
nsresult nsMsgLocalMailFolder::ChangeKeywordForMessages(nsISupportsArray *aMessages, const char *aKeywords, PRBool add)
|
||||
{
|
||||
nsresult rv = (add) ? nsMsgDBFolder::AddKeywordToMessages(aMessages, aKeyword)
|
||||
: nsMsgDBFolder::RemoveKeywordFromMessages(aMessages, aKeyword);
|
||||
nsresult rv = (add) ? nsMsgDBFolder::AddKeywordsToMessages(aMessages, aKeywords)
|
||||
: nsMsgDBFolder::RemoveKeywordsFromMessages(aMessages, aKeywords);
|
||||
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
|
@ -3945,8 +3945,6 @@ nsresult nsMsgLocalMailFolder::ChangeKeywordForMessages(nsISupportsArray *aMessa
|
|||
nsresult rv = aMessages->Count(&count);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsXPIDLCString keywords;
|
||||
nsCAutoString keywordToWrite(" ");
|
||||
keywordToWrite.Append(aKeyword);
|
||||
// for each message, we seek to the beginning of the x-mozilla-status header, and
|
||||
// start reading lines, looking for x-mozilla-keys: headers; If we're adding
|
||||
// the keyword and we find
|
||||
|
@ -3968,85 +3966,94 @@ nsresult nsMsgLocalMailFolder::ChangeKeywordForMessages(nsISupportsArray *aMessa
|
|||
nsCOMPtr<nsIMsgDBHdr> message = do_QueryElementAt(aMessages, i, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
PRUint32 messageOffset;
|
||||
PRUint32 len = 0;
|
||||
nsCAutoString header;
|
||||
nsCAutoString keywords;
|
||||
message->GetMessageOffset(&messageOffset);
|
||||
PRBool done = PR_FALSE;
|
||||
PRUint32 statusOffset = 0;
|
||||
(void)message->GetStatusOffset(&statusOffset);
|
||||
PRUint32 desiredOffset = messageOffset + statusOffset;
|
||||
fileStream->seek(PR_SEEK_SET, desiredOffset);
|
||||
PRBool inKeywordHeader = PR_FALSE;
|
||||
PRBool foundKeyword = PR_FALSE;
|
||||
PRUint32 offsetToAddKeyword = 0;
|
||||
message->GetMessageSize(&len);
|
||||
// loop through
|
||||
while (!done)
|
||||
{
|
||||
lineBuff[0] = '\0';
|
||||
PRInt32 lineStartPos = fileStream->tell();
|
||||
// readLine won't return line termination chars.
|
||||
if (fileStream->readline(lineBuff, sizeof(lineBuff)))
|
||||
{
|
||||
if (EMPTY_MESSAGE_LINE(lineBuff))
|
||||
break; // passed headers; no x-mozilla-keywords header; give up.
|
||||
nsCString keywordHeaders;
|
||||
if (!strncmp(lineBuff, HEADER_X_MOZILLA_KEYWORDS, sizeof(HEADER_X_MOZILLA_KEYWORDS) - 1))
|
||||
{
|
||||
inKeywordHeader = PR_TRUE;
|
||||
keywordHeaders = lineBuff;
|
||||
}
|
||||
else if (inKeywordHeader && (lineBuff[0] == ' ' || lineBuff[0] == '\t'))
|
||||
keywordHeaders = lineBuff;
|
||||
else if (inKeywordHeader)
|
||||
break;
|
||||
else
|
||||
continue;
|
||||
|
||||
PRInt32 keywordHdrLength = keywordHeaders.Length();
|
||||
nsACString::const_iterator start, end;
|
||||
nsACString::const_iterator keywordHdrStart;
|
||||
keywordHeaders.BeginReading(keywordHdrStart);
|
||||
// check if we have the keyword
|
||||
if (MsgFindKeyword(nsDependentCString(aKeyword), keywordHeaders, start, end))
|
||||
nsCStringArray keywordArray;
|
||||
keywordArray.ParseString(aKeywords, " ");
|
||||
for (PRInt32 j = 0; j < keywordArray.Count(); j++)
|
||||
{
|
||||
nsCAutoString header;
|
||||
nsCAutoString keywords;
|
||||
PRBool done = PR_FALSE;
|
||||
PRUint32 len = 0;
|
||||
nsCAutoString keywordToWrite(" ");
|
||||
|
||||
keywordToWrite.Append(*(keywordArray[j]));
|
||||
fileStream->seek(PR_SEEK_SET, desiredOffset);
|
||||
PRBool inKeywordHeader = PR_FALSE;
|
||||
PRBool foundKeyword = PR_FALSE;
|
||||
PRUint32 offsetToAddKeyword = 0;
|
||||
message->GetMessageSize(&len);
|
||||
// loop through
|
||||
while (!done)
|
||||
{
|
||||
lineBuff[0] = '\0';
|
||||
PRInt32 lineStartPos = fileStream->tell();
|
||||
// readLine won't return line termination chars.
|
||||
if (fileStream->readline(lineBuff, sizeof(lineBuff)))
|
||||
{
|
||||
foundKeyword = PR_TRUE;
|
||||
if (!add) // if we're removing, remove it, and break;
|
||||
if (EMPTY_MESSAGE_LINE(lineBuff))
|
||||
break; // passed headers; no x-mozilla-keywords header; give up.
|
||||
nsCString keywordHeaders;
|
||||
if (!strncmp(lineBuff, HEADER_X_MOZILLA_KEYWORDS, sizeof(HEADER_X_MOZILLA_KEYWORDS) - 1))
|
||||
{
|
||||
PRInt32 keywordStartOffset = Distance(keywordHdrStart, start);
|
||||
keywordHeaders.Cut(keywordStartOffset, Distance(start, end));
|
||||
for (PRInt32 i = Distance(start, end); i > 0; i--)
|
||||
keywordHeaders.Append(' ');
|
||||
fileStream->seek(PR_SEEK_SET, lineStartPos);
|
||||
fileStream->write(keywordHeaders.get(), keywordHeaders.Length());
|
||||
inKeywordHeader = PR_TRUE;
|
||||
keywordHeaders = lineBuff;
|
||||
}
|
||||
else if (inKeywordHeader && (lineBuff[0] == ' ' || lineBuff[0] == '\t'))
|
||||
keywordHeaders = lineBuff;
|
||||
else if (inKeywordHeader)
|
||||
break;
|
||||
else
|
||||
continue;
|
||||
|
||||
PRInt32 keywordHdrLength = keywordHeaders.Length();
|
||||
nsACString::const_iterator start, end;
|
||||
nsACString::const_iterator keywordHdrStart;
|
||||
keywordHeaders.BeginReading(keywordHdrStart);
|
||||
// check if we have the keyword
|
||||
if (MsgFindKeyword(*(keywordArray[j]), keywordHeaders, start, end))
|
||||
{
|
||||
foundKeyword = PR_TRUE;
|
||||
if (!add) // if we're removing, remove it, and break;
|
||||
{
|
||||
PRInt32 keywordStartOffset = Distance(keywordHdrStart, start);
|
||||
keywordHeaders.Cut(keywordStartOffset, Distance(start, end));
|
||||
for (PRInt32 i = Distance(start, end); i > 0; i--)
|
||||
keywordHeaders.Append(' ');
|
||||
fileStream->seek(PR_SEEK_SET, lineStartPos);
|
||||
fileStream->write(keywordHeaders.get(), keywordHeaders.Length());
|
||||
}
|
||||
offsetToAddKeyword = 0;
|
||||
// if adding and we already have the keyword, done
|
||||
done = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
// argh, we need to check all the lines to see if we already have the
|
||||
// keyword, but if we don't find it, we want to remember the line and
|
||||
// position where we have room to add the keyword.
|
||||
if (add)
|
||||
{
|
||||
nsCAutoString curKeywordHdr(lineBuff);
|
||||
// strip off line ending spaces.
|
||||
curKeywordHdr.Trim(" ", PR_FALSE, PR_TRUE);
|
||||
if (!offsetToAddKeyword && curKeywordHdr.Length() + keywordToWrite.Length() < keywordHdrLength)
|
||||
offsetToAddKeyword = lineStartPos + curKeywordHdr.Length();
|
||||
}
|
||||
offsetToAddKeyword = 0;
|
||||
// if adding and we already have the keyword, done
|
||||
done = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
// argh, we need to check all the lines to see if we already have the
|
||||
// keyword, but if we don't find it, we want to remember the line and
|
||||
// position where we have room to add the keyword.
|
||||
if (add)
|
||||
{
|
||||
nsCAutoString curKeywordHdr(lineBuff);
|
||||
// strip off line ending spaces.
|
||||
curKeywordHdr.Trim(" ", PR_FALSE, PR_TRUE);
|
||||
if (!offsetToAddKeyword && curKeywordHdr.Length() + keywordToWrite.Length() < keywordHdrLength)
|
||||
offsetToAddKeyword = lineStartPos + curKeywordHdr.Length();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (add && !foundKeyword)
|
||||
{
|
||||
if (!offsetToAddKeyword)
|
||||
message->SetUint32Property("growKeywords", 1);
|
||||
else
|
||||
if (add && !foundKeyword)
|
||||
{
|
||||
fileStream->seek(PR_SEEK_SET, offsetToAddKeyword);
|
||||
fileStream->write(keywordToWrite.get(), keywordToWrite.Length());
|
||||
if (!offsetToAddKeyword)
|
||||
message->SetUint32Property("growKeywords", 1);
|
||||
else
|
||||
{
|
||||
fileStream->seek(PR_SEEK_SET, offsetToAddKeyword);
|
||||
fileStream->write(keywordToWrite.get(), keywordToWrite.Length());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4055,7 +4062,7 @@ nsresult nsMsgLocalMailFolder::ChangeKeywordForMessages(nsISupportsArray *aMessa
|
|||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgLocalMailFolder::RemoveKeywordFromMessages(nsISupportsArray *aMessages, const char *aKeyword)
|
||||
NS_IMETHODIMP nsMsgLocalMailFolder::RemoveKeywordsFromMessages(nsISupportsArray *aMessages, const char *aKeywords)
|
||||
{
|
||||
return ChangeKeywordForMessages(aMessages, aKeyword, PR_FALSE /* remove */);
|
||||
return ChangeKeywordForMessages(aMessages, aKeywords, PR_FALSE /* remove */);
|
||||
}
|
||||
|
|
|
@ -197,8 +197,8 @@ public:
|
|||
NS_IMETHOD FetchMsgPreviewText(nsMsgKey *aKeysToFetch, PRUint32 aNumKeys,
|
||||
PRBool aLocalOnly, nsIUrlListener *aUrlListener,
|
||||
PRBool *aAsyncResults);
|
||||
NS_IMETHOD AddKeywordToMessages(nsISupportsArray *aMessages, const char *aKeyword);
|
||||
NS_IMETHOD RemoveKeywordFromMessages(nsISupportsArray *aMessages, const char *aKeyword);
|
||||
NS_IMETHOD AddKeywordsToMessages(nsISupportsArray *aMessages, const char *aKeywords);
|
||||
NS_IMETHOD RemoveKeywordsFromMessages(nsISupportsArray *aMessages, const char *aKeywords);
|
||||
|
||||
protected:
|
||||
nsresult CopyFolderAcrossServer(nsIMsgFolder *srcFolder, nsIMsgWindow *msgWindow,nsIMsgCopyServiceListener* listener);
|
||||
|
|
|
@ -1959,7 +1959,7 @@ NS_IMETHODIMP nsParseNewMailState::ApplyFilterHit(nsIMsgFilter *filter, nsIMsgWi
|
|||
nsCOMPtr<nsISupportsArray> messageArray;
|
||||
NS_NewISupportsArray(getter_AddRefs(messageArray));
|
||||
messageArray->AppendElement(msgHdr);
|
||||
m_downloadFolder->AddKeywordToMessages(messageArray, keyword.get());
|
||||
m_downloadFolder->AddKeywordsToMessages(messageArray, keyword.get());
|
||||
break;
|
||||
}
|
||||
case nsMsgFilterAction::Label:
|
||||
|
|
|
@ -402,6 +402,12 @@ net_pop3_write_state(Pop3UidlHost* host, nsIFileSpec *mailDirectory)
|
|||
nsFileSpec fileSpec;
|
||||
mailDirectory->GetFileSpec(&fileSpec);
|
||||
fileSpec += "popstate.dat";
|
||||
#ifdef DEBUG_David_Bienvenu
|
||||
PRUint32 fileSize = fileSpec.GetFileSize();
|
||||
// check if popstate.dat is getting emptied out.
|
||||
if (!host || (hash_empty(host->hash) && fileSize > 80))
|
||||
NS_ASSERTION(PR_FALSE, "bad/empty pop3 uidl hash table");
|
||||
#endif
|
||||
|
||||
nsOutputFileStream outFileStream(fileSpec, PR_WRONLY | PR_CREATE_FILE |
|
||||
PR_TRUNCATE);
|
||||
|
|
|
@ -846,7 +846,7 @@ NS_IMETHODIMP nsNNTPNewsgroupList::ApplyFilterHit(nsIMsgFilter *aFilter, nsIMsgW
|
|||
messageArray->AppendElement(m_newMsgHdr);
|
||||
nsCOMPtr <nsIMsgFolder> folder = do_QueryInterface(m_newsFolder, &rv);
|
||||
if (folder)
|
||||
folder->AddKeywordToMessages(messageArray, keyword.get());
|
||||
folder->AddKeywordsToMessages(messageArray, keyword.get());
|
||||
break;
|
||||
}
|
||||
case nsMsgFilterAction::Label:
|
||||
|
|
Загрузка…
Ссылка в новой задаче