fix 66771 add match all search term for filters and virtual folders, sr=mscott

This commit is contained in:
bienvenu%nventure.com 2006-05-30 20:02:41 +00:00
Родитель ee7d824917
Коммит 28402a3247
15 изменённых файлов: 113 добавлений и 42 удалений

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

@ -1016,6 +1016,11 @@ function getSearchTermString(searchTerms)
if (condition.length > 1)
condition += ' ';
if (term.matchAll)
{
condition = "ALL";
break;
}
condition += (term.booleanAnd) ? "AND (" : "OR (";
condition += term.termAsString + ')';
}

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

@ -2,6 +2,8 @@
<!ENTITY matchAll.accesskey "a">
<!ENTITY matchAny.label "Match any of the following">
<!ENTITY matchAny.accesskey "o">
<!ENTITY matchAllMsgs.label "Match all messages">
<!ENTITY matchAllMsgs.accesskey "m">
<!-- LOCALIZATION NOTE
The values below are used to control the widths of the search widgets.

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

@ -1040,6 +1040,11 @@ function getSearchTermString(searchTerms)
if (condition.length > 1)
condition += ' ';
if (term.matchAll)
{
condition = "ALL";
break;
}
condition += (term.booleanAnd) ? "AND (" : "OR (";
condition += term.termAsString + ')';
}

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

@ -55,8 +55,8 @@ interface nsIMsgSearchTerm : nsISupports {
attribute boolean booleanAnd;
attribute string arbitraryHeader;
attribute boolean beginsGrouping;
attribute boolean endsGrouping;
attribute boolean beginsGrouping;
attribute boolean endsGrouping;
boolean matchRfc822String(in string aString, in string charset, in boolean charsetOverride);
boolean matchRfc2047String(in string aString, in string charset, in boolean charsetOverride);
@ -65,8 +65,8 @@ interface nsIMsgSearchTerm : nsISupports {
boolean matchPriority(in nsMsgPriorityValue priority);
boolean matchAge(in PRTime days);
boolean matchSize(in unsigned long size);
boolean matchLabel(in nsMsgLabelValue aLabelValue);
boolean matchJunkStatus(in string aJunkScore);
boolean matchLabel(in nsMsgLabelValue aLabelValue);
boolean matchJunkStatus(in string aJunkScore);
boolean matchBody(in nsIMsgSearchScopeTerm scopeTerm,
in unsigned long offset,
@ -93,5 +93,6 @@ interface nsIMsgSearchTerm : nsISupports {
readonly attribute boolean matchAllBeforeDeciding;
readonly attribute ACString termAsString;
attribute boolean matchAll;
};

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

@ -105,6 +105,7 @@ public:
nsMsgSearchBooleanOperator m_booleanOp; // boolean operator to be applied to this search term and the search term which precedes it.
nsCString m_arbitraryHeader; // user specified string for the name of the arbitrary header to be used in the search
// only has a value when m_attribute = attribOtherHeader!!!!
PRBool m_matchAll; // does this term match all headers?
protected:
nsresult MatchString (const char *stringToMatch, const char *charset,

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

@ -314,7 +314,8 @@ function initializeSearchWindowWidgets()
gFolderPicker = document.getElementById("searchableFolders");
gSearchStopButton = document.getElementById("search-button");
gStatusBar = document.getElementById('statusbar-icon');
hideMatchAllItem();
msgWindow = Components.classes[msgWindowContractID].createInstance(nsIMsgWindow);
msgWindow.statusFeedback = gStatusFeedback;
msgWindow.SetDOMWindow(window);

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

@ -22,6 +22,7 @@
* Contributor(s):
* Alec Flett <alecf@netscape.com>
* Seth Spitzer <sspitzer@netscape.com>
* David Bienvenu <bienvenu@nventure.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
@ -142,6 +143,7 @@ searchTermContainer.prototype = {
this.searchvalue.saveTo(searchTerm.value);
searchTerm.value = this.searchvalue.value;
searchTerm.booleanAnd = this.booleanAnd;
searchTerm.matchAll = this.matchAll;
},
// if you have a search term element with no search term
saveTo: function(searchTerm) {
@ -166,13 +168,21 @@ function initializeSearchWidgets()
function initializeBooleanWidgets()
{
var booleanAnd = true;
var matchAll = false;
// get the boolean value from the first term
var firstTerm = gSearchTerms[0].searchTerm;
if (firstTerm)
{
booleanAnd = firstTerm.booleanAnd;
// target radio items have value="and" or value="or"
gSearchBooleanRadiogroup.value = booleanAnd ? "and" : "or";
matchAll = firstTerm.matchAll;
}
// target radio items have value="and" or value="or" or "all"
gSearchBooleanRadiogroup.value = matchAll
? "matchAll"
: (booleanAnd ? "and" : "or")
var searchTerms = document.getElementById("searchTermList");
if (searchTerms)
searchTerms.hidden = matchAll;
}
function initializeSearchRows(scope, searchTerms)
@ -257,6 +267,7 @@ function updateSearchAttributes()
function booleanChanged(event) {
// when boolean changes, we have to update all the attributes on the search terms
var newBoolValue = (event.target.getAttribute("value") == "and") ? true : false;
var matchAllValue = (event.target.getAttribute("value") == "matchAll") ? true : false;
if (document.getElementById("abPopup")) {
var selectedAB = document.getElementById("abPopup").selectedItem.id;
setSearchScope(GetScopeForDirectoryURI(selectedAB));
@ -264,6 +275,14 @@ function booleanChanged(event) {
for (var i=0; i<gSearchTerms.length; i++) {
var searchTerm = gSearchTerms[i].obj;
searchTerm.booleanAnd = newBoolValue;
searchTerm.matchAll = matchAllValue;
}
var searchTerms = document.getElementById("searchTermList");
if (searchTerms)
{
if (!matchAllValue && searchTerms.hidden)
onMore(null); // fake to get empty row.
searchTerms.hidden = matchAllValue;
}
}
@ -452,6 +471,7 @@ function removeSearchRow(index)
// via XPCOM)
function saveSearchTerms(searchTerms, termOwner)
{
var matchAll = gSearchBooleanRadiogroup.value == 'matchAll';
var i;
for (i = 0; i<gSearchTerms.length; i++) {
try {
@ -463,7 +483,7 @@ function saveSearchTerms(searchTerms, termOwner)
// is an existing term, but not initialize, so skip saving
continue;
}
searchTerm.matchAll = matchAll;
if (searchTerm)
gSearchTerms[i].obj.save();
else {
@ -485,7 +505,6 @@ function saveSearchTerms(searchTerms, termOwner)
gSearchRemovedTerms[i].QueryInterface(Components.interfaces.nsISupports);
searchTerms.RemoveElement(searchTermSupports);
}
}
function onReset(event)
@ -495,6 +514,13 @@ function onReset(event)
onMore(null);
}
function hideMatchAllItem()
{
var allItems = document.getElementById('matchAllItem');
if (allItems)
allItems.hidden = true;
}
// this is a helper routine used by our search term xbl widget
var gLabelStrings = new Array;
function GetLabelStrings()

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

@ -51,6 +51,7 @@
selectedItem="or" oncommand="booleanChanged(event);">
<radio value="and" label="&matchAll.label;" accesskey="&matchAll.accesskey;"/>
<radio selected="true" value="or" label="&matchAny.label;" accesskey="&matchAny.accesskey;"/>
<radio value="matchAll" id="matchAllItem" label="&matchAllMsgs.label;" accesskey="&matchAllMsgs.accesskey;"/>
</radiogroup>
<hbox flex="1">

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

@ -1,13 +0,0 @@
<!ENTITY matchAll.label "Match all of the following">
<!ENTITY matchAll.accesskey "a">
<!ENTITY matchAny.label "Match any of the following">
<!ENTITY matchAny.accesskey "o">
<!-- LOCALIZATION NOTE
The values below are used to control the widths of the search widgets.
Change the values only when the localized strings in the popup menus
are truncated in the widgets.
-->
<!ENTITY searchTermListAttributesFlexValue "5">
<!ENTITY searchTermListOperatorsFlexValue "5">
<!ENTITY searchTermListValueFlexValue "5">
<!ENTITY searchTermListButtonsFlexValue "2">

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

@ -749,33 +749,40 @@ nsresult nsMsgFilter::SaveRule(nsIOFileStream *aStream)
PRUint32 count;
m_termList->Count(&count);
for (searchIndex = 0; searchIndex < count && NS_SUCCEEDED(err);
searchIndex++)
searchIndex++)
{
nsCAutoString stream;
nsCOMPtr<nsIMsgSearchTerm> term;
m_termList->QueryElementAt(searchIndex, NS_GET_IID(nsIMsgSearchTerm),
(void **)getter_AddRefs(term));
if (!term)
continue;
if (condition.Length() > 1)
condition += ' ';
PRBool booleanAnd;
PRBool matchAll;
term->GetBooleanAnd(&booleanAnd);
if (booleanAnd)
term->GetMatchAll(&matchAll);
if (matchAll)
{
condition += "ALL";
break;
}
else if (booleanAnd)
condition += "AND (";
else
condition += "OR (";
nsresult searchError = term->GetTermAsString(stream);
if (NS_FAILED(searchError))
{
err = searchError;
break;
}
condition += stream;
condition += ')';
}

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

@ -115,7 +115,6 @@ protected:
PRPackedBool m_enabled;
PRPackedBool m_temporary;
PRPackedBool m_unparseable;
nsIMsgFilterList *m_filterList; /* owning filter list */
nsCOMPtr<nsISupportsArray> m_termList; /* linked list of criteria terms */
nsCOMPtr<nsIMsgSearchScopeTerm> m_scope; /* default for mail rules is inbox, but news rules could

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

@ -719,11 +719,24 @@ nsresult nsMsgFilterList::LoadTextFilters(nsIOFileStream *aStream)
// what about values with close parens and quotes? e.g., (body, isn't, "foo")")
// I guess interior quotes will need to be escaped - ("foo\")")
// which will get written out as (\"foo\\")\") and read in as ("foo\")"
// ALL means match all messages.
NS_IMETHODIMP nsMsgFilterList::ParseCondition(nsIMsgFilter *aFilter, const char *aCondition)
{
PRBool done = PR_FALSE;
nsresult err = NS_OK;
const char *curPtr = aCondition;
if (!strcmp(aCondition, "ALL"))
{
nsMsgSearchTerm *newTerm = new nsMsgSearchTerm;
if (newTerm)
{
newTerm->m_matchAll = PR_TRUE;
aFilter->AppendTerm(newTerm);
}
return (newTerm) ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
while (!done)
{
// insert code to save the boolean operator if there is one for this search term....

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

@ -441,9 +441,16 @@ nsresult nsMsgSearchOfflineMail::ProcessSearchTerm(nsIMsgDBHdr *msgToMatch,
PRBool charsetOverride = PR_FALSE; /* XXX BUG 68706 */
PRUint32 msgFlags;
PRBool result;
PRBool matchAll;
NS_ENSURE_ARG_POINTER(pResult);
aTerm->GetMatchAll(&matchAll);
if (matchAll)
{
*pResult = PR_TRUE;
return NS_OK;
}
*pResult = PR_FALSE;
nsMsgSearchAttribValue attrib;

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

@ -22,6 +22,7 @@
* Contributor(s):
* Seth Spitzer <sspitzer@netscape.com>
* Jungshik Shin <jshin@mailaps.org>
* David Bienvenu <bienvenu@nventure.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
@ -342,6 +343,7 @@ nsMsgSearchTerm::nsMsgSearchTerm()
m_attribute = nsMsgSearchAttrib::Default;
mBeginsGrouping = PR_FALSE;
mEndsGrouping = PR_FALSE;
m_matchAll = PR_FALSE;
}
nsMsgSearchTerm::nsMsgSearchTerm (
@ -357,6 +359,7 @@ nsMsgSearchTerm::nsMsgSearchTerm (
if (attrib > nsMsgSearchAttrib::OtherHeader && attrib < nsMsgSearchAttrib::kNumMsgSearchAttributes && arbitraryHeader)
m_arbitraryHeader = arbitraryHeader;
nsMsgResultElement::AssignValues (val, &m_value);
m_matchAll = PR_FALSE;
}
@ -495,6 +498,11 @@ NS_IMETHODIMP nsMsgSearchTerm::GetTermAsString (nsACString &outStream)
nsCAutoString outputStr;
nsresult ret;
if (m_matchAll)
{
outStream = "ALL";
return NS_OK;
}
ret = NS_MsgGetStringForAttribute(m_attribute, &attrib);
if (ret != NS_OK)
return ret;
@ -641,18 +649,23 @@ nsMsgSearchTerm::ParseAttribute(char *inStream, nsMsgSearchAttribValue *attrib)
nsresult nsMsgSearchTerm::DeStreamNew (char *inStream, PRInt16 /*length*/)
{
char *commaSep = PL_strchr(inStream, ',');
nsresult rv = ParseAttribute(inStream, &m_attribute); // will allocate space for arbitrary header if necessary
if (!strcmp(inStream, "ALL"))
{
m_matchAll = PR_TRUE;
return NS_OK;
}
char *commaSep = PL_strchr(inStream, ',');
nsresult rv = ParseAttribute(inStream, &m_attribute); // will allocate space for arbitrary header if necessary
NS_ENSURE_SUCCESS(rv, rv);
if (!commaSep)
return NS_ERROR_INVALID_ARG;
char *secondCommaSep = PL_strchr(commaSep + 1, ',');
if (commaSep)
rv = ParseOperator(commaSep + 1, &m_operator);
if (!commaSep)
return NS_ERROR_INVALID_ARG;
char *secondCommaSep = PL_strchr(commaSep + 1, ',');
if (commaSep)
rv = ParseOperator(commaSep + 1, &m_operator);
NS_ENSURE_SUCCESS(rv, rv);
if (secondCommaSep)
ParseValue(secondCommaSep + 1);
return NS_OK;
if (secondCommaSep)
ParseValue(secondCommaSep + 1);
return NS_OK;
}
@ -1369,7 +1382,7 @@ nsresult nsMsgSearchTerm::InitHeaderAddressParser()
NS_IMPL_GETSET(nsMsgSearchTerm, Attrib, nsMsgSearchAttribValue, m_attribute)
NS_IMPL_GETSET(nsMsgSearchTerm, Op, nsMsgSearchOpValue, m_operator)
NS_IMPL_GETSET(nsMsgSearchTerm, MatchAll, PRBool, m_matchAll)
NS_IMETHODIMP
nsMsgSearchTerm::GetValue(nsIMsgSearchValue **aResult)

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

@ -118,6 +118,9 @@ function initializeMailViewOverrides()
//orButton.setAttribute('label', 'Any of the following');
//var andButton = document.getElementById('and');
//andButton.setAttribute('label', 'All of the following');
// matchAll doesn't make sense for views, since views are a single folder
hideMatchAllItem();
}
function UpdateAfterCustomHeaderChange()