diff options
author | Matt A. Tobin <email@mattatobin.com> | 2019-11-03 00:17:46 -0400 |
---|---|---|
committer | Matt A. Tobin <email@mattatobin.com> | 2019-11-03 00:17:46 -0400 |
commit | 302bf1b523012e11b60425d6eee1221ebc2724eb (patch) | |
tree | b191a895f8716efcbe42f454f37597a545a6f421 /mailnews/base/search/public | |
parent | 21b3f6247403c06f85e1f45d219f87549862198f (diff) | |
download | UXP-302bf1b523012e11b60425d6eee1221ebc2724eb.tar UXP-302bf1b523012e11b60425d6eee1221ebc2724eb.tar.gz UXP-302bf1b523012e11b60425d6eee1221ebc2724eb.tar.lz UXP-302bf1b523012e11b60425d6eee1221ebc2724eb.tar.xz UXP-302bf1b523012e11b60425d6eee1221ebc2724eb.zip |
Issue #1258 - Part 1: Import mailnews, ldap, and mork from comm-esr52.9.1
Diffstat (limited to 'mailnews/base/search/public')
26 files changed, 2520 insertions, 0 deletions
diff --git a/mailnews/base/search/public/moz.build b/mailnews/base/search/public/moz.build new file mode 100644 index 000000000..60eb4a18a --- /dev/null +++ b/mailnews/base/search/public/moz.build @@ -0,0 +1,38 @@ +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +XPIDL_SOURCES += [ + 'nsIMsgFilter.idl', + 'nsIMsgFilterCustomAction.idl', + 'nsIMsgFilterHitNotify.idl', + 'nsIMsgFilterList.idl', + 'nsIMsgFilterPlugin.idl', + 'nsIMsgFilterService.idl', + 'nsIMsgOperationListener.idl', + 'nsIMsgSearchAdapter.idl', + 'nsIMsgSearchCustomTerm.idl', + 'nsIMsgSearchNotify.idl', + 'nsIMsgSearchScopeTerm.idl', + 'nsIMsgSearchSession.idl', + 'nsIMsgSearchTerm.idl', + 'nsIMsgSearchValidityManager.idl', + 'nsIMsgSearchValidityTable.idl', + 'nsIMsgSearchValue.idl', + 'nsIMsgTraitService.idl', + 'nsMsgFilterCore.idl', + 'nsMsgSearchCore.idl', +] + +XPIDL_MODULE = 'msgsearch' + +EXPORTS += [ + 'nsMsgBodyHandler.h', + 'nsMsgResultElement.h', + 'nsMsgSearchAdapter.h', + 'nsMsgSearchBoolExpression.h', + 'nsMsgSearchScopeTerm.h', + 'nsMsgSearchTerm.h', +] + diff --git a/mailnews/base/search/public/nsIMsgFilter.idl b/mailnews/base/search/public/nsIMsgFilter.idl new file mode 100644 index 000000000..5571b2f9a --- /dev/null +++ b/mailnews/base/search/public/nsIMsgFilter.idl @@ -0,0 +1,142 @@ +/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +#include "nsISupports.idl" +#include "nsMsgFilterCore.idl" +// Disable deprecation warnings generated by nsISupportsArray and associated +// classes. +%{C++ +#if defined(__GNUC__) +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#elif defined(_MSC_VER) +#pragma warning (disable : 4996) +#endif +%} +interface nsISupportsArray; + +interface nsIArray; +interface nsIOutputStream; +interface nsIMsgFilterCustomAction; +interface nsIMsgFilterList; +interface nsIMsgSearchScopeTerm; +interface nsIMsgSearchValue; +interface nsIMsgSearchTerm; + +[scriptable, uuid(36d2748e-9246-44f3-bb74-46cbb0b8c23a)] +interface nsIMsgRuleAction : nsISupports { + + attribute nsMsgRuleActionType type; + + // target priority.. throws an exception if the action is not priority + attribute nsMsgPriorityValue priority; + + // target folder.. throws an exception if the action is not move to folder + attribute ACString targetFolderUri; + + // target label. throws an exception if the action is not label + attribute nsMsgLabelValue label; + + attribute long junkScore; + + attribute AUTF8String strValue; + + // action id if type is Custom + attribute ACString customId; + + // custom action associated with customId + // (which must be set prior to reading this attribute) + readonly attribute nsIMsgFilterCustomAction customAction; + +}; + +[scriptable, uuid(d304fcfc-b588-11e4-981c-770e1e5d46b0)] +interface nsIMsgFilter : nsISupports { + attribute nsMsgFilterTypeType filterType; + /** + * some filters are "temporary". For example, the filters we create when the user + * filters return receipts to the Sent folder. + * we don't show temporary filters in the UI + * and we don't write them to disk. + */ + attribute boolean temporary; + attribute boolean enabled; + attribute AString filterName; + attribute ACString filterDesc; + attribute ACString unparsedBuffer; //holds the entire filter if we don't know how to handle it + attribute boolean unparseable; //whether we could parse the filter or not + + attribute nsIMsgFilterList filterList; // owning filter list + + void AddTerm(in nsMsgSearchAttribValue attrib, + in nsMsgSearchOpValue op, + in nsIMsgSearchValue value, + in boolean BooleanAND, + in ACString arbitraryHeader); + + void GetTerm(in long termIndex, + out nsMsgSearchAttribValue attrib, + out nsMsgSearchOpValue op, + out nsIMsgSearchValue value, // bad! using shared structure + out boolean BooleanAND, + out ACString arbitraryHeader); + + void appendTerm(in nsIMsgSearchTerm term); + + nsIMsgSearchTerm createTerm(); + + attribute nsISupportsArray searchTerms; + + attribute nsIMsgSearchScopeTerm scope; + + // Marking noscript because "headers" is actually a null-separated + // list of headers, which is not scriptable. + [noscript] void MatchHdr(in nsIMsgDBHdr msgHdr, in nsIMsgFolder folder, + in nsIMsgDatabase db, + in string headers, + // [array, size_is(headerSize)] in string headers, + in unsigned long headerSize, out boolean result); + + + /* + * Report that Rule was matched and executed when filter logging is enabled. + * + * @param aFilterAction The filter rule that was invoked. + * @param aHeader The header information of the message acted on by + * the filter. + */ + void logRuleHit(in nsIMsgRuleAction aFilterAction, + in nsIMsgDBHdr aHeader); + + /* Report that filtering failed for some reason when filter logging is enabled. + * + * @param aFilterAction Filter rule that was invoked. + * @param aHeader Header of the message acted on by the filter. + * @param aRcode Error code returned by low-level routine that + * led to the filter failure. + * @param aErrmsg Error message + */ + void logRuleHitFail(in nsIMsgRuleAction aFilterAction, + in nsIMsgDBHdr aHeader, + in nsresult aRcode, + in string aErrmsg ); + + nsIMsgRuleAction createAction(); + + nsIMsgRuleAction getActionAt(in unsigned long aIndex); + + long getActionIndex(in nsIMsgRuleAction aAction); + + void appendAction(in nsIMsgRuleAction action); + + readonly attribute unsigned long actionCount; + + void clearActionList(); + + // Returns the action list in the order it will be really executed in. + readonly attribute nsIArray sortedActionList; + + void SaveToTextFile(in nsIOutputStream aStream); +}; diff --git a/mailnews/base/search/public/nsIMsgFilterCustomAction.idl b/mailnews/base/search/public/nsIMsgFilterCustomAction.idl new file mode 100644 index 000000000..d3a1c5584 --- /dev/null +++ b/mailnews/base/search/public/nsIMsgFilterCustomAction.idl @@ -0,0 +1,90 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsMsgFilterCore.idl" + +interface nsIArray; +interface nsIMsgCopyServiceListener; +interface nsIMsgWindow; + +/** + * describes a custom action added to a message filter + */ +[scriptable,uuid(4699C41E-3671-436e-B6AE-4FD8106747E4)] +interface nsIMsgFilterCustomAction : nsISupports +{ + /* globally unique string to identify this filter action. + * recommended form: ExtensionName@example.com#ActionName + */ + readonly attribute ACString id; + + /* action name to display in action list. This should be localized. */ + readonly attribute AString name; + + /** + * Is this custom action valid for a particular filter type? + * + * @param type the filter type + * @param scope the search scope + * + * @return true if valid + */ + boolean isValidForType(in nsMsgFilterTypeType type, in nsMsgSearchScopeValue scope); + + /** + * After the user inputs a particular action value for the action, determine + * if that value is valid. + * + * @param actionValue The value entered. + * @param actionFolder Folder in the filter list + * @param filterType Filter Type (Manual, OfflineMail, etc.) + * + * @return errorMessage A localized message to display if invalid + * Set to null if the actionValue is valid + */ + AUTF8String validateActionValue(in AUTF8String actionValue, + in nsIMsgFolder actionFolder, + in nsMsgFilterTypeType filterType); + + /* allow duplicate actions in the same filter list? Default No. */ + attribute boolean allowDuplicates; + + /* + * The custom action itself + * + * Generally for the apply method, folder-based methods give correct + * results and are preferred if available. Otherwise, be careful + * that the action does correct notifications to maintain counts, and correct + * manipulations of both IMAP and local non-database storage of message + * metadata. + */ + + /** + * Apply the custom action to an array of messages + * + * @param msgHdrs array of nsIMsgDBHdr objects of messages + * @param actionValue user-set value to use in the action + * @param copyListener calling method (filterType Manual only) + * @param filterType type of filter being applied + * @param msgWindow message window + */ + + void apply(in nsIArray msgHdrs /* nsIMsgDBHdr array */, + in AUTF8String actionValue, + in nsIMsgCopyServiceListener copyListener, + in nsMsgFilterTypeType filterType, + in nsIMsgWindow msgWindow); + + /* does this action start an async action? If so, a copy listener must + * be used to continue filter processing after the action. This only + * applies to after-the-fact (manual) filters. Call OnStopCopy when done + * using the copyListener to continue. + */ + readonly attribute boolean isAsync; + + /// Does this action need the message body? + readonly attribute boolean needsBody; +}; + + diff --git a/mailnews/base/search/public/nsIMsgFilterHitNotify.idl b/mailnews/base/search/public/nsIMsgFilterHitNotify.idl new file mode 100644 index 000000000..d85226e60 --- /dev/null +++ b/mailnews/base/search/public/nsIMsgFilterHitNotify.idl @@ -0,0 +1,27 @@ +/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsISupports.idl" + +interface nsIMsgFilter; +interface nsIMsgWindow; + +/////////////////////////////////////////////////////////////////////////////// +// nsIMsgFilterHitNotify is an interface designed to make evaluating filters +// easier. Clients typically open a filter list and ask the filter list to +// evaluate the filters for a particular message, and pass in an +// interface pointer to be notified of hits. The filter list will call the +// ApplyFilterHit method on the interface pointer in case of hits, along with +// the desired action and value. +// return value is used to indicate whether the +// filter list should continue trying to apply filters or not. +// +/////////////////////////////////////////////////////////////////////////////// + +[scriptable, uuid(c9f15174-1f3f-11d3-a51b-0060b0fc04b7)] +interface nsIMsgFilterHitNotify : nsISupports { + boolean applyFilterHit(in nsIMsgFilter filter, in nsIMsgWindow msgWindow); +}; + diff --git a/mailnews/base/search/public/nsIMsgFilterList.idl b/mailnews/base/search/public/nsIMsgFilterList.idl new file mode 100644 index 000000000..b9c24b526 --- /dev/null +++ b/mailnews/base/search/public/nsIMsgFilterList.idl @@ -0,0 +1,108 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsISupports.idl" +#include "nsIMsgFilterHitNotify.idl" +#include "nsMsgFilterCore.idl" + +interface nsIFile; +interface nsIOutputStream; +interface nsIMsgFilter; +interface nsIMsgFolder; + +/////////////////////////////////////////////////////////////////////////////// +// The Msg Filter List is an interface designed to make accessing filter lists +// easier. Clients typically open a filter list and either enumerate the filters, +// or add new filters, or change the order around... +// +/////////////////////////////////////////////////////////////////////////////// + +typedef long nsMsgFilterFileAttribValue; + +[scriptable, uuid(5d0ec03e-7e2f-49e9-b58a-b274c85f279e)] +interface nsIMsgFilterList : nsISupports { + + const nsMsgFilterFileAttribValue attribNone = 0; + const nsMsgFilterFileAttribValue attribVersion = 1; + const nsMsgFilterFileAttribValue attribLogging = 2; + const nsMsgFilterFileAttribValue attribName = 3; + const nsMsgFilterFileAttribValue attribEnabled = 4; + const nsMsgFilterFileAttribValue attribDescription = 5; + const nsMsgFilterFileAttribValue attribType = 6; + const nsMsgFilterFileAttribValue attribScriptFile = 7; + const nsMsgFilterFileAttribValue attribAction = 8; + const nsMsgFilterFileAttribValue attribActionValue = 9; + const nsMsgFilterFileAttribValue attribCondition = 10; + const nsMsgFilterFileAttribValue attribCustomId = 11; + + attribute nsIMsgFolder folder; + readonly attribute short version; + readonly attribute ACString arbitraryHeaders; + readonly attribute boolean shouldDownloadAllHeaders; + readonly attribute unsigned long filterCount; + nsIMsgFilter getFilterAt(in unsigned long filterIndex); + nsIMsgFilter getFilterNamed(in AString filterName); + + void setFilterAt(in unsigned long filterIndex, in nsIMsgFilter filter); + void removeFilter(in nsIMsgFilter filter); + void removeFilterAt(in unsigned long filterIndex); + + void moveFilterAt(in unsigned long filterIndex, + in nsMsgFilterMotionValue motion); + void moveFilter(in nsIMsgFilter filter, + in nsMsgFilterMotionValue motion); + + void insertFilterAt(in unsigned long filterIndex, in nsIMsgFilter filter); + + attribute boolean loggingEnabled; + + nsIMsgFilter createFilter(in AString name); + + void saveToFile(in nsIOutputStream stream); + + void parseCondition(in nsIMsgFilter aFilter, in string condition); + // this is temporary so that we can save the filterlist to disk + // without knowing where the filters were read from intially + // (such as the filter list dialog) + attribute nsIFile defaultFile; + void saveToDefaultFile(); + + + // marking noscript because headers is a null-separated list + // of strings, which is not scriptable + [noscript] + void applyFiltersToHdr(in nsMsgFilterTypeType filterType, + in nsIMsgDBHdr msgHdr, + in nsIMsgFolder folder, + in nsIMsgDatabase db, + in string headers, + //[array, size_is(headerSize)] in string headers, + in unsigned long headerSize, + in nsIMsgFilterHitNotify listener, + in nsIMsgWindow msgWindow); + + // IO routines, used by filter object filing code. + void writeIntAttr(in nsMsgFilterFileAttribValue attrib, in long value, in nsIOutputStream stream); + void writeStrAttr(in nsMsgFilterFileAttribValue attrib, in string value, in nsIOutputStream stream); + void writeWstrAttr(in nsMsgFilterFileAttribValue attrib, in wstring value, in nsIOutputStream stream); + void writeBoolAttr(in nsMsgFilterFileAttribValue attrib, in boolean value, in nsIOutputStream stream); + boolean matchOrChangeFilterTarget(in ACString oldUri, in ACString newUri, in boolean caseInsensitive); + + // for filter logging + // If both attributes are fetched successfully, they guarantee + // the log file exists and is set up with a header. + attribute nsIOutputStream logStream; + readonly attribute ACString logURL; + void clearLog(); + void flushLogIfNecessary(); +}; + + +/* these longs are all actually of type nsMsgFilterMotionValue */ +[scriptable, uuid(d067b528-304e-11d3-a0e1-00a0c900d445)] +interface nsMsgFilterMotion { + const long up = 0; + const long down = 1; +}; diff --git a/mailnews/base/search/public/nsIMsgFilterPlugin.idl b/mailnews/base/search/public/nsIMsgFilterPlugin.idl new file mode 100644 index 000000000..9632471c2 --- /dev/null +++ b/mailnews/base/search/public/nsIMsgFilterPlugin.idl @@ -0,0 +1,350 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsISupports.idl" +#include "MailNewsTypes2.idl" + +interface nsIMsgWindow; +interface nsIFile; + +/** + * This interface is still very much under development, and is not yet stable. + */ + +[scriptable, uuid(e2e56690-a676-11d6-80c9-00008646b737)] +interface nsIMsgFilterPlugin : nsISupports +{ + /** + * Do any necessary cleanup: flush and close any open files, etc. + */ + void shutdown(); + + /** + * Some protocols (ie IMAP) can, as an optimization, avoid + * downloading all message header lines. If your plugin doesn't need + * any more than the minimal set, it can return false for this attribute. + */ + readonly attribute boolean shouldDownloadAllHeaders; + +}; + +/* + * These interfaces typically implement a Bayesian classifier of messages. + * + * Two sets of interfaces may be used: the older junk-only interfaces, and + * the newer trait-oriented interfaces that treat junk classification as + * one of a set of classifications to accomplish. + */ + +[scriptable, uuid(b15a0f9c-df07-4af0-9ba8-80dca68ac35d)] +interface nsIJunkMailClassificationListener : nsISupports +{ + /** + * Inform a listener of a message's classification as junk. At the end + * of a batch of classifications, signify end of batch by calling with + * null aMsgURI (other parameters are don't care) + * + * @param aMsgURI URI of the message that was classified. + * @param aClassification classification of message as UNCLASSIFIED, GOOD, + * or JUNK. + * @param aJunkPercent indicator of degree of uncertainty, with 100 being + * probably junk, and 0 probably good + */ + void onMessageClassified(in string aMsgURI, + in nsMsgJunkStatus aClassification, + in uint32_t aJunkPercent); +}; + +[scriptable, uuid(AF247D07-72F0-482d-9EAB-5A786407AA4C)] +interface nsIMsgTraitClassificationListener : nsISupports +{ + /** + * Inform a listener of a message's match to traits. The list + * of traits being matched is in aTraits. Corresponding + * indicator of match (percent) is in aPercents. At the end + * of a batch of classifications, signify end of batch by calling with + * null aMsgURI (other parameters are don't care) + * + * @param aMsgURI URI of the message that was classified + * @param aTraitCount length of aTraits and aPercents arrays + * @param aTraits array of matched trait ids + * @param aPercents array of percent match (0 is unmatched, 100 is fully + * matched) of the trait with the corresponding array + * index in aTraits + */ + void onMessageTraitsClassified(in string aMsgURI, + in unsigned long aTraitCount, + [array, size_is(aTraitCount)] in unsigned long aTraits, + [array, size_is(aTraitCount)] in unsigned long aPercents); +}; + +[scriptable, uuid(12667532-88D1-44a7-AD48-F73719BE5C92)] +interface nsIMsgTraitDetailListener : nsISupports +{ + /** + * Inform a listener of details of a message's match to traits. + * This returns the tokens that were used in the calculation, + * the calculated percent probability that each token matches the trait, + * and a running estimate (starting with the strongest tokens) of the + * combined total probability that a message matches the trait, when + * only tokens stronger than the current token are used. + * + * @param aMsgURI URI of the message that was classified + * @param aProTrait trait id of pro trait for the calculation + * @param tokenCount length of arrays that follow + * @param tokenStrings the string for a particular token + * @param tokenPercents calculated probability that a message with that token + * matches the trait + * @param runningPercents calculated probability that the message matches the + * trait, accounting for this token and all stronger tokens. + */ + void onMessageTraitDetails(in string aMsgUri, + in unsigned long aProTrait, + in unsigned long tokenCount, + [array, size_is(tokenCount)] in wstring tokenStrings, + [array, size_is(tokenCount)] in unsigned long tokenPercents, + [array, size_is(tokenCount)] in unsigned long runningPercents); +}; + +[scriptable, uuid(8EA5BBCA-F735-4d43-8541-D203D8E2FF2F)] +interface nsIJunkMailPlugin : nsIMsgFilterPlugin +{ + /** + * Message classifications. + */ + const nsMsgJunkStatus UNCLASSIFIED = 0; + const nsMsgJunkStatus GOOD = 1; + const nsMsgJunkStatus JUNK = 2; + + /** + * Message junk score constants. Junkscore can only be one of these two + * values (or not set). + */ + const nsMsgJunkScore IS_SPAM_SCORE = 100; // junk + const nsMsgJunkScore IS_HAM_SCORE = 0; // not junk + + /** + * Trait ids for junk analysis. These values are fixed to ensure + * backwards compatibility with existing junk-oriented classification + * code. + */ + + const unsigned long GOOD_TRAIT = 1; // good + const unsigned long JUNK_TRAIT = 2; // junk + + /** + * Given a message URI, determine what its current classification is + * according to the current training set. + */ + void classifyMessage(in string aMsgURI, in nsIMsgWindow aMsgWindow, + in nsIJunkMailClassificationListener aListener); + + void classifyMessages(in unsigned long aCount, + [array, size_is(aCount)] in string aMsgURIs, + in nsIMsgWindow aMsgWindow, + in nsIJunkMailClassificationListener aListener); + + /** + * Given a message URI, evaluate its relative match to a list of + * traits according to the current training set. + * + * @param aMsgURI URI of the message to be evaluated + * @param aTraitCount length of aProTraits, aAntiTraits arrays + * @param aProTraits array of trait ids for trained messages that + * match the tested trait (for example, + * JUNK_TRAIT if testing for junk) + * @param aAntiTraits array of trait ids for trained messages that + * do not match the tested trait (for example, + * GOOD_TRAIT if testing for junk) + * @param aTraitListener trait-oriented callback listener (may be null) + * @param aMsgWindow current message window (may be null) + * @param aJunkListener junk-oriented callback listener (may be null) + */ + + void classifyTraitsInMessage( + in string aMsgURI, + in unsigned long aTraitCount, + [array, size_is(aTraitCount)] in unsigned long aProTraits, + [array, size_is(aTraitCount)] in unsigned long aAntiTraits, + in nsIMsgTraitClassificationListener aTraitListener, + [optional] in nsIMsgWindow aMsgWindow, + [optional] in nsIJunkMailClassificationListener aJunkListener); + + /** + * Given an array of message URIs, evaluate their relative match to a + * list of traits according to the current training set. + * + * @param aCount Number of messages to evaluate + * @param aMsgURIs array of URIs of the messages to be evaluated + * @param aTraitCount length of aProTraits, aAntiTraits arrays + * @param aProTraits array of trait ids for trained messages that + * match the tested trait (for example, + * JUNK_TRAIT if testing for junk) + * @param aAntiTraits array of trait ids for trained messages that + * do not match the tested trait (for example, + * GOOD_TRAIT if testing for junk) + * @param aTraitListener trait-oriented callback listener (may be null) + * @param aMsgWindow current message window (may be null) + * @param aJunkListener junk-oriented callback listener (may be null) + */ + + void classifyTraitsInMessages( + in unsigned long aCount, + [array, size_is(aCount)] in string aMsgURIs, + in unsigned long aTraitCount, + [array, size_is(aTraitCount)] in unsigned long aProTraits, + [array, size_is(aTraitCount)] in unsigned long aAntiTraits, + in nsIMsgTraitClassificationListener aTraitListener, + [optional] in nsIMsgWindow aMsgWindow, + [optional] in nsIJunkMailClassificationListener aJunkListener); + + /** + * Called when a user forces the classification of a message. Should + * cause the training set to be updated appropriately. + * + * @arg aMsgURI URI of the message to be classified + * @arg aOldUserClassification Was it previous manually classified + * by the user? If so, how? + * @arg aNewClassification New manual classification. + * @arg aListener Callback (may be null) + */ + void setMessageClassification( + in string aMsgURI, in nsMsgJunkStatus aOldUserClassification, + in nsMsgJunkStatus aNewClassification, + in nsIMsgWindow aMsgWindow, + in nsIJunkMailClassificationListener aListener); + + /** + * Called when a user forces a change in the classification of a message. + * Should cause the training set to be updated appropriately. + * + * @param aMsgURI URI of the message to be classified + * @param aOldCount length of aOldTraits array + * @param aOldTraits array of trait IDs of the old + * message classification(s), if any + * @param aNewCount length of aNewTraits array + * @param aNewTraits array of trait IDs of the new + * message classification(s), if any + * @param aTraitListener trait-oriented listener (may be null) + * @param aMsgWindow current message window (may be null) + * @param aJunkListener junk-oriented listener (may be null) + */ + void setMsgTraitClassification( + in string aMsgURI, + in unsigned long aOldCount, + [array, size_is(aOldCount)] in unsigned long aOldTraits, + in unsigned long aNewCount, + [array, size_is(aNewCount)] in unsigned long aNewTraits, + [optional] in nsIMsgTraitClassificationListener aTraitListener, + [optional] in nsIMsgWindow aMsgWindow, + [optional] in nsIJunkMailClassificationListener aJunkListener); + + readonly attribute boolean userHasClassified; + + /** Removes the training file and clears out any in memory training tokens. + User must retrain after doing this. + **/ + void resetTrainingData(); + + /** + * Given a message URI, return a list of tokens and their contribution to + * the analysis of a message's match to a trait according to the + * current training set. + * + * @param aMsgURI URI of the message to be evaluated + * @param aProTrait trait id for trained messages that match the + * tested trait (for example, JUNK_TRAIT if testing + * for junk) + * @param aAntiTrait trait id for trained messages that do not match + * the tested trait (for example, GOOD_TRAIT + * if testing for junk) + * @param aListener callback listener for results + * @param aMsgWindow current message window (may be null) + */ + void detailMessage( + in string aMsgURI, + in unsigned long aProTrait, + in unsigned long aAntiTrait, + in nsIMsgTraitDetailListener aListener, + [optional] in nsIMsgWindow aMsgWindow); + +}; + +/** + * The nsIMsgCorpus interface manages a corpus of mail data used for + * statistical analysis of messages. + */ +[scriptable, uuid(70BAD26F-DFD4-41bd-8FAB-4C09B9C1E845)] +interface nsIMsgCorpus : nsISupports +{ + /** + * Clear the corpus data for a trait id. + * + * @param aTrait trait id + */ + void clearTrait(in unsigned long aTrait); + + /** + * Update corpus data from a file. + * + * @param aFile the file with the data, in the format: + * + * Format of the trait file for version 1: + * [0xFCA93601] (the 01 is the version) + * for each trait to write: + * [id of trait to write] (0 means end of list) + * [number of messages per trait] + * for each token with non-zero count + * [count] + * [length of word]word + * + * @param aIsAdd should the data be added, or removed? True if + * adding, false if removing. + * + * @param aRemapCount number of items in the parallel arrays aFromTraits, + * aToTraits. These arrays allow conversion of the + * trait id stored in the file (which may be originated + * externally) to the trait id used in the local corpus + * (which is defined locally using nsIMsgTraitService, and + * mapped by that interface to a globally unique trait + * id string). + * + * @param aFromTraits array of trait ids used in aFile. If aFile contains + * trait ids that are not in this array, they are not + * remapped, but assummed to be local trait ids. + * + * @param aToTraits array of trait ids, corresponding to elements of + * aFromTraits, that represent the local trait ids to + * be used in storing data from aFile into the local corpus. + */ + void updateData(in nsIFile aFile, in boolean aIsAdd, + [optional] in unsigned long aRemapCount, + [optional, array, size_is(aRemapCount)] in unsigned long aFromTraits, + [optional, array, size_is(aRemapCount)] in unsigned long aToTraits); + + /** + * Get the corpus count for a token as a string. + * + * @param aWord string of characters representing the token + * @param aTrait trait id + * + * @return count of that token in the corpus + * + */ + unsigned long getTokenCount(in AUTF8String aWord, in unsigned long aTrait); + + /** + * Gives information on token and message count information in the + * training data corpus. + * + * @param aTrait trait id (may be null) + * @param aMessageCount count of messages that have been trained with aTrait + * + * @return token count for all traits + */ + + unsigned long corpusCounts(in unsigned long aTrait, out unsigned long aMessageCount); +}; diff --git a/mailnews/base/search/public/nsIMsgFilterService.idl b/mailnews/base/search/public/nsIMsgFilterService.idl new file mode 100644 index 000000000..8cf69aeed --- /dev/null +++ b/mailnews/base/search/public/nsIMsgFilterService.idl @@ -0,0 +1,95 @@ +/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsISupports.idl" +#include "nsMsgFilterCore.idl" + +interface nsIMsgFilterList; +interface nsIMsgWindow; +interface nsIMsgFilterCustomAction; +interface nsISimpleEnumerator; +interface nsIFile; +interface nsIMsgFolder; +interface nsIMsgSearchCustomTerm; +interface nsIArray; +interface nsIMsgOperationListener; + +[scriptable, uuid(78a74023-1692-4567-8d72-9ca58fbbd427)] +interface nsIMsgFilterService : nsISupports { + + nsIMsgFilterList OpenFilterList(in nsIFile filterFile, in nsIMsgFolder rootFolder, in nsIMsgWindow msgWindow); + void CloseFilterList(in nsIMsgFilterList filterList); + + void SaveFilterList(in nsIMsgFilterList filterList, + in nsIFile filterFile); + + void CancelFilterList(in nsIMsgFilterList filterList); + nsIMsgFilterList getTempFilterList(in nsIMsgFolder aFolder); + void applyFiltersToFolders(in nsIMsgFilterList aFilterList, + in nsIArray aFolders, + in nsIMsgWindow aMsgWindow, + [optional] in nsIMsgOperationListener aCallback); + + /* + * Apply filters to a specific list of messages in a folder. + * @param aFilterType The type of filter to match against + * @param aMsgHdrList The list of message headers (nsIMsgDBHdr objects) + * @param aFolder The folder the messages belong to + * @param aMsgWindow A UI window for attaching progress/dialogs + * @param aCallback A listener that gets notified of any filtering error + */ + void applyFilters(in nsMsgFilterTypeType aFilterType, + in nsIArray aMsgHdrList, + in nsIMsgFolder aFolder, + in nsIMsgWindow aMsgWindow, + [optional] in nsIMsgOperationListener aCallback); + + /** + * add a custom filter action + * + * @param aAction the custom action to add + */ + void addCustomAction(in nsIMsgFilterCustomAction aAction); + + /** + * get the list of custom actions + * + * @return enumerator of nsIMsgFilterCustomAction objects + */ + nsISimpleEnumerator getCustomActions(); + + /** + * lookup a custom action given its id + * + * @param id unique identifier for a particular custom action + * + * @return the custom action, or null if not found + */ + nsIMsgFilterCustomAction getCustomAction(in ACString id); + + /** + * add a custom search term + * + * @param aTerm the custom term to add + */ + void addCustomTerm(in nsIMsgSearchCustomTerm aTerm); + + /** + * get the list of custom search terms + * + * @return enumerator of nsIMsgSearchCustomTerm objects + */ + nsISimpleEnumerator getCustomTerms(); + + /** + * lookup a custom search term given its id + * + * @param id unique identifier for a particular custom search term + * + * @return the custom search term, or null if not found + */ + nsIMsgSearchCustomTerm getCustomTerm(in ACString id); + +}; diff --git a/mailnews/base/search/public/nsIMsgOperationListener.idl b/mailnews/base/search/public/nsIMsgOperationListener.idl new file mode 100644 index 000000000..30751cd5c --- /dev/null +++ b/mailnews/base/search/public/nsIMsgOperationListener.idl @@ -0,0 +1,17 @@ +/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsISupports.idl" + +// Listener used to notify when an operation has completed. +[scriptable, uuid(bdaef6ff-0909-435b-8fcd-76525dd2364c)] +interface nsIMsgOperationListener : nsISupports { + /** + * Called when the operation stops (possibly with errors) + * + * @param aStatus Success or failure of the operation + */ + void onStopOperation(in nsresult aStatus); +}; diff --git a/mailnews/base/search/public/nsIMsgSearchAdapter.idl b/mailnews/base/search/public/nsIMsgSearchAdapter.idl new file mode 100644 index 000000000..b818939a1 --- /dev/null +++ b/mailnews/base/search/public/nsIMsgSearchAdapter.idl @@ -0,0 +1,42 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +#include "nsISupports.idl" +#include "nsIMsgSearchScopeTerm.idl" + +[ptr] native nsMsgResultElement(nsMsgResultElement); + +%{C++ +class nsMsgResultElement; +%} + +[scriptable, uuid(0b09078b-e0cd-440a-afee-01f45808ee74)] +interface nsIMsgSearchAdapter : nsISupports { + void ValidateTerms(); + void Search(out boolean done); + void SendUrl(); + void CurrentUrlDone(in nsresult exitCode); + + void AddHit(in nsMsgKey key); + void AddResultElement(in nsIMsgDBHdr aHdr); + + [noscript] void OpenResultElement(in nsMsgResultElement element); + [noscript] void ModifyResultElement(in nsMsgResultElement element, + in nsMsgSearchValue value); + + readonly attribute string encoding; + + [noscript] nsIMsgFolder FindTargetFolder([const] in nsMsgResultElement + element); + void Abort(); + void getSearchCharsets(out AString srcCharset, out AString destCharset); + /* + * Clear the saved scope reference. This is used when deleting scope, which is not + * reference counted in nsMsgSearchSession + */ + void clearScope(); +}; + diff --git a/mailnews/base/search/public/nsIMsgSearchCustomTerm.idl b/mailnews/base/search/public/nsIMsgSearchCustomTerm.idl new file mode 100644 index 000000000..3983eb1a3 --- /dev/null +++ b/mailnews/base/search/public/nsIMsgSearchCustomTerm.idl @@ -0,0 +1,79 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsMsgSearchCore.idl" + +/** + * describes a custom term added to a message search or filter + */ +[scriptable,uuid(925DB5AA-21AF-494c-8652-984BC7BAD13A)] +interface nsIMsgSearchCustomTerm : nsISupports +{ + /** + * globally unique string to identify this search term. + * recommended form: ExtensionName@example.com#TermName + * Commas and quotes are not allowed, the id must not + * parse to an integer, and names of standard search + * attributes in SearchAttribEntryTable in nsMsgSearchTerm.cpp + * are not allowed. + */ + readonly attribute ACString id; + + /// name to display in term list. This should be localized. */ + readonly attribute AString name; + + /// Does this term need the message body? + readonly attribute boolean needsBody; + + /** + * Is this custom term enabled? + * + * @param scope search scope (nsMsgSearchScope) + * @param op search operator (nsMsgSearchOp). If null, determine + * if term is available for any operator. + * + * @return true if enabled + */ + boolean getEnabled(in nsMsgSearchScopeValue scope, + in nsMsgSearchOpValue op); + + /** + * Is this custom term available? + * + * @param scope search scope (nsMsgSearchScope) + * @param op search operator (nsMsgSearchOp). If null, determine + * if term is available for any operator. + * + * @return true if available + */ + boolean getAvailable(in nsMsgSearchScopeValue scope, + in nsMsgSearchOpValue op); + + /** + * List the valid operators for this term. + * + * @param scope search scope (nsMsgSearchScope) + * @param length object to hold array length + * + * @return array of operators + */ + void getAvailableOperators(in nsMsgSearchScopeValue scope, + out unsigned long length, + [retval, array, size_is(length)] + out nsMsgSearchOpValue operators); + + /** + * Apply the custom search term to a message + * + * @param msgHdr header database reference representing the message + * @param searchValue user-set value to use in the search + * @param searchOp search operator (Contains, IsHigherThan, etc.) + * + * @return true if the term matches the message, else false + */ + + boolean match(in nsIMsgDBHdr msgHdr, + in AUTF8String searchValue, + in nsMsgSearchOpValue searchOp); +}; diff --git a/mailnews/base/search/public/nsIMsgSearchNotify.idl b/mailnews/base/search/public/nsIMsgSearchNotify.idl new file mode 100644 index 000000000..c602f708c --- /dev/null +++ b/mailnews/base/search/public/nsIMsgSearchNotify.idl @@ -0,0 +1,31 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsISupports.idl" + +interface nsIMsgDBHdr; +interface nsIMsgSearchSession; +interface nsIMsgFolder; + +// when a search is run, this interface is passed in as a listener +// on the search. +[scriptable, uuid(ca37784d-352b-4c39-8ccb-0abc1a93f681)] +interface nsIMsgSearchNotify : nsISupports +{ + void onSearchHit(in nsIMsgDBHdr header, in nsIMsgFolder folder); + + // notification that a search has finished. + void onSearchDone(in nsresult status); + /* + * until we can encode searches with a URI, this will be an + * out-of-bound way to connect a set of search terms to a datasource + */ + + /* + * called when a new search begins + */ + void onNewSearch(); +}; + diff --git a/mailnews/base/search/public/nsIMsgSearchScopeTerm.idl b/mailnews/base/search/public/nsIMsgSearchScopeTerm.idl new file mode 100644 index 000000000..32c590979 --- /dev/null +++ b/mailnews/base/search/public/nsIMsgSearchScopeTerm.idl @@ -0,0 +1,20 @@ +/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsIMsgSearchSession.idl" + +interface nsIMsgFolder; +interface nsIMsgDBHdr; +interface nsILineInputStream; +interface nsIInputStream; + +[scriptable, uuid(934672c3-9b8f-488a-935d-87b4023fa0be)] +interface nsIMsgSearchScopeTerm : nsISupports { + nsIInputStream getInputStream(in nsIMsgDBHdr aHdr); + void closeInputStream(); + readonly attribute nsIMsgFolder folder; + readonly attribute nsIMsgSearchSession searchSession; +}; + diff --git a/mailnews/base/search/public/nsIMsgSearchSession.idl b/mailnews/base/search/public/nsIMsgSearchSession.idl new file mode 100644 index 000000000..36ed7409e --- /dev/null +++ b/mailnews/base/search/public/nsIMsgSearchSession.idl @@ -0,0 +1,147 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsISupports.idl" +#include "nsIMsgSearchValue.idl" + +interface nsIMsgSearchAdapter; +interface nsIMsgSearchTerm; +interface nsIMsgSearchNotify; +interface nsIMsgHdr; +interface nsIMsgDatabase; +// Disable deprecation warnings generated by nsISupportsArray and associated +// classes. +%{C++ +#if defined(__GNUC__) +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#elif defined(_MSC_VER) +#pragma warning (disable : 4996) +#endif +%} +interface nsISupportsArray; +interface nsIMsgWindow; + +////////////////////////////////////////////////////////////////////////////// +// The Msg Search Session is an interface designed to make constructing +// searches easier. Clients typically build up search terms, and then run +// the search +////////////////////////////////////////////////////////////////////////////// + +[scriptable, uuid(1ed69bbf-7983-4602-9a9b-2f2263a78878)] +interface nsIMsgSearchSession : nsISupports { + +/** + * add a search term to the search session + * + * @param attrib search attribute (e.g. nsMsgSearchAttrib::Subject) + * @param op search operator (e.g. nsMsgSearchOp::Contains) + * @param value search value (e.g. "Dogbert", see nsIMsgSearchValue) + * @param BooleanAND set to true if associated boolean operator is AND + * @param customString if attrib > nsMsgSearchAttrib::OtherHeader, + * a user defined arbitrary header + * if attrib == nsMsgSearchAttrib::Custom, the custom id + * otherwise ignored + */ + void addSearchTerm(in nsMsgSearchAttribValue attrib, + in nsMsgSearchOpValue op, + in nsIMsgSearchValue value, + in boolean BooleanAND, + in string customString); + + readonly attribute nsISupportsArray searchTerms; + + nsIMsgSearchTerm createTerm (); + void appendTerm(in nsIMsgSearchTerm term); + + /** + * @name Search notification flags + * These flags determine which notifications will be sent. + * @{ + */ + /// search started notification + const long onNewSearch = 0x1; + + /// search finished notification + const long onSearchDone = 0x2; + + /// search hit notification + const long onSearchHit = 0x4; + + const long allNotifications = 0x7; + /** @} */ + + /** + * Add a listener to get notified of search starts, stops, and hits. + * + * @param aListener listener + * @param aNotifyFlags which notifications to send. Defaults to all + */ + void registerListener (in nsIMsgSearchNotify aListener, + [optional] in long aNotifyFlags); + void unregisterListener (in nsIMsgSearchNotify listener); + + readonly attribute unsigned long numSearchTerms; + + readonly attribute nsIMsgSearchAdapter runningAdapter; + + void getNthSearchTerm(in long whichTerm, + in nsMsgSearchAttribValue attrib, + in nsMsgSearchOpValue op, + in nsIMsgSearchValue value); // wrong, should be out + + long countSearchScopes(); + + void getNthSearchScope(in long which,out nsMsgSearchScopeValue scopeId, out nsIMsgFolder folder); + + /* add a scope (e.g. a mail folder) to the search */ + void addScopeTerm(in nsMsgSearchScopeValue scope, + in nsIMsgFolder folder); + + void addDirectoryScopeTerm(in nsMsgSearchScopeValue scope); + + void clearScopes(); + + /* Call this function everytime the scope changes! It informs the FE if + the current scope support custom header use. FEs should not display the + custom header dialog if custom headers are not supported */ + [noscript] boolean ScopeUsesCustomHeaders(in nsMsgSearchScopeValue scope, + /* could be a folder or server based on scope */ + in voidPtr selection, + in boolean forFilters); + + /* use this to determine if your attribute is a string attrib */ + boolean IsStringAttribute(in nsMsgSearchAttribValue attrib); + + /* add all scopes of a given type to the search */ + void AddAllScopes(in nsMsgSearchScopeValue attrib); + + void search(in nsIMsgWindow aWindow); + void interruptSearch(); + + // these two methods are used when the search session is using + // a timer to do local search, and the search adapter needs + // to run a url (e.g., to reparse a local folder) and wants to + // pause the timer while running the url. This will fail if the + // current adapter is not using a timer. + void pauseSearch(); + void resumeSearch(); + + [noscript] readonly attribute voidPtr searchParam; + readonly attribute nsMsgSearchType searchType; + + [noscript] nsMsgSearchType SetSearchParam(in nsMsgSearchType type, + in voidPtr param); + + boolean MatchHdr(in nsIMsgDBHdr aMsgHdr, in nsIMsgDatabase aDatabase); + + void addSearchHit(in nsIMsgDBHdr header, in nsIMsgFolder folder); + + readonly attribute long numResults; + attribute nsIMsgWindow window; + + /* these longs are all actually of type nsMsgSearchBooleanOp */ + const long BooleanOR=0; + const long BooleanAND=1; +}; diff --git a/mailnews/base/search/public/nsIMsgSearchTerm.idl b/mailnews/base/search/public/nsIMsgSearchTerm.idl new file mode 100644 index 000000000..e464ecd70 --- /dev/null +++ b/mailnews/base/search/public/nsIMsgSearchTerm.idl @@ -0,0 +1,156 @@ +/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsISupports.idl" +#include "nsMsgSearchCore.idl" +#include "nsIMsgSearchValue.idl" + +interface nsIMsgDBHdr; +interface nsIMsgDatabase; +interface nsIMsgSearchScopeTerm; + +[scriptable, uuid(705a2b5a-5efc-495c-897a-bef1161cd3c0)] +interface nsIMsgSearchTerm : nsISupports { + attribute nsMsgSearchAttribValue attrib; + attribute nsMsgSearchOpValue op; + attribute nsIMsgSearchValue value; + + attribute boolean booleanAnd; + attribute ACString arbitraryHeader; + /** + * Not to be confused with arbitraryHeader, which is a header in the + * rfc822 message. This is a property of the nsIMsgDBHdr, and may have + * nothing to do the message headers, e.g., gloda-id. + * value.str will be compared with nsIMsgHdr::GetProperty(hdrProperty). + */ + attribute ACString hdrProperty; + + /// identifier for a custom id used for this term, if any. + attribute ACString customId; + + attribute boolean beginsGrouping; + attribute boolean endsGrouping; + + /** + * Match the value against one of the emails found in the incoming + * 2047-encoded string. + */ + boolean matchRfc822String(in ACString aString, in string charset); + /** + * Match the current header value against the incoming 2047-encoded string. + * + * This method will first apply the nsIMimeConverter decoding to the string + * (using the supplied parameters) and will then match the value against the + * decoded result. + */ + boolean matchRfc2047String(in ACString aString, in string charset, in boolean charsetOverride); + boolean matchDate(in PRTime aTime); + boolean matchStatus(in unsigned long aStatus); + 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); + /* + * Test search term match for junkpercent + * + * @param aJunkPercent junkpercent for message (0-100, 100 is junk) + * @return true if matches + */ + boolean matchJunkPercent(in unsigned long aJunkPercent); + /* + * Test search term match for junkscoreorigin + * @param aJunkScoreOrigin Who set junk score? Possible values: + * plugin filter imapflag user whitelist + * @return true if matches + */ + boolean matchJunkScoreOrigin(in string aJunkScoreOrigin); + + /** + * Test if the body of the passed in message matches "this" search term. + * @param aScopeTerm scope of search + * @param aOffset offset of message in message store. + * @param aLength length of message. + * @param aCharset folder charset. + * @param aMsg db msg hdr of message to match. + * @param aDB db containing msg header. + */ + boolean matchBody(in nsIMsgSearchScopeTerm aScopeTerm, + in unsigned long long aOffset, + in unsigned long aLength, + in string aCharset, + in nsIMsgDBHdr aMsg, + in nsIMsgDatabase aDb); + + /** + * Test if the arbitrary header specified by this search term + * matches the corresponding header in the passed in message. + * + * @param aScopeTerm scope of search + * @param aLength length of message + * @param aCharset The charset to apply to un-labeled non-UTF-8 data. + * @param aCharsetOverride If true, aCharset is used instead of any + * charset labeling other than UTF-8. + * + * N.B. This is noscript because headers is a null-separated list of + * strings, which is not scriptable. + */ + [noscript] + boolean matchArbitraryHeader(in nsIMsgSearchScopeTerm aScopeTerm, + in unsigned long aLength, + in string aCharset, + in boolean aCharsetOverride, + in nsIMsgDBHdr aMsg, + in nsIMsgDatabase aDb, + //[array, size_is(headerLength)] in string headers, + in string aHeaders, + in unsigned long aHeaderLength, + in boolean aForFilters); + + /** + * Compares value.str with nsIMsgHdr::GetProperty(hdrProperty). + * @param msg msg to match db hdr property of. + * + * @returns true if msg matches property, false otherwise. + */ + boolean matchHdrProperty(in nsIMsgDBHdr msg); + + /** + * Compares value.status with nsIMsgHdr::GetUint32Property(hdrProperty). + * @param msg msg to match db hdr property of. + * + * @returns true if msg matches property, false otherwise. + */ + boolean matchUint32HdrProperty(in nsIMsgDBHdr msg); + + /** + * Compares value.status with the folder flags of the msg's folder. + * @param msg msgHdr whose folder's flag we want to compare. + * + * @returns true if folder's flags match value.status, false otherwise. + */ + boolean matchFolderFlag(in nsIMsgDBHdr msg); + + readonly attribute boolean matchAllBeforeDeciding; + + readonly attribute ACString termAsString; + boolean matchKeyword(in ACString keyword); // used for tag searches + attribute boolean matchAll; + /** + * Does the message match the custom search term? + * + * @param msg message database object representing the message + * + * @return true if message matches + */ + boolean matchCustom(in nsIMsgDBHdr msg); + + /** + * Returns a nsMsgSearchAttribValue value corresponding to a field string from + * the nsMsgSearchTerm.cpp::SearchAttribEntryTable table. + * Does not handle custom attributes yet. + */ + nsMsgSearchAttribValue getAttributeFromString(in string aAttribName); +}; diff --git a/mailnews/base/search/public/nsIMsgSearchValidityManager.idl b/mailnews/base/search/public/nsIMsgSearchValidityManager.idl new file mode 100644 index 000000000..dbc7958bd --- /dev/null +++ b/mailnews/base/search/public/nsIMsgSearchValidityManager.idl @@ -0,0 +1,26 @@ +/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsISupports.idl" +#include "nsIMsgSearchValidityTable.idl" + +typedef long nsMsgSearchValidityScope; + +[scriptable, uuid(6A352055-DE6E-49d2-A256-89E0B9EC405E)] +interface nsIMsgSearchValidityManager : nsISupports { + nsIMsgSearchValidityTable getTable(in nsMsgSearchValidityScope scope); + + /** + * Given a search attribute (which is an internal numerical id), return + * the string name that you can use as a key to look up the localized + * string in the search-attributes.properties file. + * + * @param aSearchAttribute attribute type from interface nsMsgSearchAttrib + * + * @return localization-friendly string representation + * of the attribute + */ + AString getAttributeProperty(in nsMsgSearchAttribValue aSearchAttribute); +}; diff --git a/mailnews/base/search/public/nsIMsgSearchValidityTable.idl b/mailnews/base/search/public/nsIMsgSearchValidityTable.idl new file mode 100644 index 000000000..43856c88b --- /dev/null +++ b/mailnews/base/search/public/nsIMsgSearchValidityTable.idl @@ -0,0 +1,50 @@ +/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsISupports.idl" +#include "nsMsgSearchCore.idl" +// Disable deprecation warnings generated by nsISupportsArray and associated +// classes. +%{C++ +#if defined(__GNUC__) +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#elif defined(_MSC_VER) +#pragma warning (disable : 4996) +#endif +%} +interface nsISupportsArray; + +[scriptable, uuid(b07f1cb6-fae9-4d92-9edb-03f9ad249c66)] +interface nsIMsgSearchValidityTable : nsISupports { + + void setAvailable(in nsMsgSearchAttribValue attrib, + in nsMsgSearchOpValue op, in boolean active); + void setEnabled(in nsMsgSearchAttribValue attrib, + in nsMsgSearchOpValue op, in boolean enabled); + void setValidButNotShown(in nsMsgSearchAttribValue attrib, + in nsMsgSearchOpValue op, in boolean valid); + + boolean getAvailable(in nsMsgSearchAttribValue attrib, + in nsMsgSearchOpValue op); + boolean getEnabled(in nsMsgSearchAttribValue attrib, + in nsMsgSearchOpValue op); + boolean getValidButNotShown(in nsMsgSearchAttribValue attrib, + in nsMsgSearchOpValue op); + + [noscript] void validateTerms(in nsISupportsArray terms); + + readonly attribute long numAvailAttribs; + + void getAvailableAttributes(out unsigned long length, + [retval, array, size_is(length)] + out nsMsgSearchAttribValue attrs); + + void getAvailableOperators(in nsMsgSearchAttribValue attrib, + out unsigned long length, + [retval, array, size_is(length)] + out nsMsgSearchOpValue operators); + + void setDefaultAttrib(in nsMsgSearchAttribValue defaultAttrib); +}; diff --git a/mailnews/base/search/public/nsIMsgSearchValue.idl b/mailnews/base/search/public/nsIMsgSearchValue.idl new file mode 100644 index 000000000..f6d4845bd --- /dev/null +++ b/mailnews/base/search/public/nsIMsgSearchValue.idl @@ -0,0 +1,36 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsMsgSearchCore.idl" + +interface nsIMsgFolder; + +[scriptable, uuid(783758a0-cdb5-11dc-95ff-0800200c9a66)] +interface nsIMsgSearchValue : nsISupports { + // type of object + attribute nsMsgSearchAttribValue attrib; + + // accessing these will throw an exception if the above + // attribute does not match the type! + attribute AString str; + attribute nsMsgPriorityValue priority; + attribute PRTime date; + // see nsMsgMessageFlags.idl and nsMsgFolderFlags.idl + attribute unsigned long status; + attribute unsigned long size; + attribute nsMsgKey msgKey; + attribute long age; // in days + attribute nsIMsgFolder folder; + attribute nsMsgLabelValue label; + attribute nsMsgJunkStatus junkStatus; + /* + * junkPercent is set by the message filter plugin, and is approximately + * proportional to the probability that a message is junk. + * (range 0-100, 100 is junk) + */ + attribute unsigned long junkPercent; + + AString toString(); +}; diff --git a/mailnews/base/search/public/nsIMsgTraitService.idl b/mailnews/base/search/public/nsIMsgTraitService.idl new file mode 100644 index 000000000..78d9704e3 --- /dev/null +++ b/mailnews/base/search/public/nsIMsgTraitService.idl @@ -0,0 +1,174 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + /** + * This interface provides management of traits that are used to categorize + * messages. A trait is some characteristic of a message, such as being "junk" + * or "personal", that may be discoverable by analysis of the message. + * + * Traits are described by a universal identifier "id" as a string, as well + * as a local integer identifer "index". One purpose of this service is to + * provide the mapping between those forms. + * + * Recommended (but not required) format for id: + * "extensionName@example.org#traitName" + */ + +#include "nsISupports.idl" + +[scriptable, uuid(2CB15FB0-A912-40d3-8882-F2765C75655F)] +interface nsIMsgTraitService : nsISupports +{ + /** + * the highest ever index for a registered trait. The first trait is 1, + * == 0 means no traits are defined + */ + readonly attribute long lastIndex; + + /** + * Register a trait. May be called multiple times, but subsequent + * calls do not register the trait + * + * @param id the trait universal identifier + * + * @return the internal index for the registered trait if newly + * registered, else 0 + */ + unsigned long registerTrait(in ACString id); + + /** + * Unregister a trait. + * + * @param id the trait universal identifier + */ + void unRegisterTrait(in ACString id); + + /** + * is a trait registered? + * + * @param id the trait universal identifier + * + * @return true if registered + */ + boolean isRegistered(in ACString id); + + /** + * set the trait name, which is an optional short description of the trait + * + * @param id the trait universal identifier + * @param name description of the trait. + */ + void setName(in ACString id, in ACString name); + + /** + * get the trait name, which is an optional short description of the trait + * + * @param id the trait universal identifier + * + * @return description of the trait + */ + ACString getName(in ACString id); + + /** + * get the internal index number for the trait. + * + * @param id the trait universal identifier + * + * @return internal index number for the trait + */ + unsigned long getIndex(in ACString id); + + /** + * get the trait universal identifier for an internal trait index + * + * @param index the internal identifier for the trait + * + * @return trait universal identifier + */ + ACString getId(in unsigned long index); + + /** + * enable the trait for analysis. Each enabled trait will be analyzed by + * the bayesian code. The enabled trait is the "pro" trait that represents + * messages matching the trait. Each enabled trait also needs a corresponding + * anti trait defined, which represents messages that do not match the trait. + * The anti trait does not need to be enabled + * + * @param id the trait universal identifier + * @param enabled should this trait be processed by the bayesian analyzer? + */ + void setEnabled(in ACString id, in boolean enabled); + + /** + * Should this trait be processed by the bayes analyzer? + * + * @param id the trait universal identifier + * + * @return true if this is a "pro" trait to process + */ + boolean getEnabled(in ACString id); + + /** + * set the anti trait, which indicates messages that have been marked as + * NOT matching a particular trait. + * + * @param id the trait universal identifier + * @param antiId trait id for messages marked as not matching the trait + */ + void setAntiId(in ACString id, in ACString antiId); + + /** + * get the id of traits that do not match a particular trait + * + * @param id the trait universal identifier for a "pro" trait + * + * @return universal trait identifier for an "anti" trait that does not + * match the "pro" trait messages + */ + ACString getAntiId(in ACString id); + + /** + * get an array of traits to be analyzed by the bayesian code. This is + * a pair of traits: a "pro" trait of messages that match the trait (and is + * set enabled) and an "anti" trait of messages that do not match the trait. + * + * @param count length of proIndices and antiIndices arrays + * @param proIndices trait internal index for "pro" trait to analyze + * @param antiIndices trait internal index for corresponding "anti" traits + */ + void getEnabledIndices(out unsigned long count, + [array, size_is(count)] out unsigned long proIndices, + [array, size_is(count)] out unsigned long antiIndices); + + /** + * Add a trait as an alias of another trait. An alias is a trait whose + * counts will be combined with the aliased trait. This allows multiple sets + * of corpus data to be used to provide information on a single message + * characteristic, while allowing each individual set of corpus data to + * retain its own identity. + * + * @param aTraitIndex the internal identifier for the aliased trait + * @param aTraitAlias the internal identifier for the alias to add + */ + void addAlias(in unsigned long aTraitIndex, in unsigned long aTraitAlias); + + /** + * Removes a trait as an alias of another trait. + * + * @param aTraitIndex the internal identifier for the aliased trait + * @param aTraitAlias the internal identifier for the alias to remove + */ + void removeAlias(in unsigned long aTraitIndex, in unsigned long aTraitAlias); + + /** + * Get an array of trait aliases for a trait index, if any + * + * @param aTraitIndex the internal identifier for the aliased trait + * @param aLength length of array of aliases + * @param aAliases array of internal identifiers for aliases + */ + void getAliases(in unsigned long aTraitIndex, out unsigned long aLength, + [retval, array, size_is(aLength)] out unsigned long aAliases); + +}; diff --git a/mailnews/base/search/public/nsMsgBodyHandler.h b/mailnews/base/search/public/nsMsgBodyHandler.h new file mode 100644 index 000000000..417f166d6 --- /dev/null +++ b/mailnews/base/search/public/nsMsgBodyHandler.h @@ -0,0 +1,112 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +#ifndef __nsMsgBodyHandler_h +#define __nsMsgBodyHandler_h + +#include "nsIMsgSearchScopeTerm.h" +#include "nsILineInputStream.h" +#include "nsIMsgDatabase.h" + +//--------------------------------------------------------------------------- +// nsMsgBodyHandler: used to retrieve lines from POP and IMAP offline messages. +// This is a helper class used by nsMsgSearchTerm::MatchBody +//--------------------------------------------------------------------------- +class nsMsgBodyHandler +{ +public: + nsMsgBodyHandler (nsIMsgSearchScopeTerm *, + uint32_t length, + nsIMsgDBHdr * msg, + nsIMsgDatabase * db); + + // we can also create a body handler when doing arbitrary header + // filtering...we need the list of headers and the header size as well + // if we are doing filtering...if ForFilters is false, headers and + // headersSize is ignored!!! + nsMsgBodyHandler (nsIMsgSearchScopeTerm *, + uint32_t length, nsIMsgDBHdr * msg, nsIMsgDatabase * db, + const char * headers /* NULL terminated list of headers */, + uint32_t headersSize, bool ForFilters); + + virtual ~nsMsgBodyHandler(); + + // Returns next message line in buf and the applicable charset, if found. + // The return value is the length of 'buf' or -1 for EOF. + int32_t GetNextLine(nsCString &buf, nsCString &charset); + + // Transformations + void SetStripHtml (bool strip) { m_stripHtml = strip; } + void SetStripHeaders (bool strip) { m_stripHeaders = strip; } + +protected: + void Initialize(); // common initialization code + + // filter related methods. For filtering we always use the headers + // list instead of the database... + bool m_Filtering; + int32_t GetNextFilterLine(nsCString &buf); + // pointer into the headers list in the original message hdr db... + const char * m_headers; + uint32_t m_headersSize; + uint32_t m_headerBytesRead; + + // local / POP related methods + void OpenLocalFolder(); + + // goes through the mail folder + int32_t GetNextLocalLine(nsCString &buf); + + nsIMsgSearchScopeTerm *m_scope; + nsCOMPtr <nsILineInputStream> m_fileLineStream; + nsCOMPtr <nsIFile> m_localFile; + + /** + * The number of lines in the message. If |m_lineCountInBodyLines| then this + * is the number of body lines, otherwise this is the entire number of lines + * in the message. This is important so we know when to stop reading the file + * without accidentally reading part of the next message. + */ + uint32_t m_numLocalLines; + /** + * When true, |m_numLocalLines| is the number of body lines in the message, + * when false it is the entire number of lines in the message. + * + * When a message is an offline IMAP or news message, then the number of lines + * will be the entire number of lines, so this should be false. When the + * message is a local message, the number of lines will be the number of body + * lines. + */ + bool m_lineCountInBodyLines; + + // Offline IMAP related methods & state + + + nsCOMPtr<nsIMsgDBHdr> m_msgHdr; + nsCOMPtr<nsIMsgDatabase> m_db; + + // Transformations + // With the exception of m_isMultipart, these all apply to the various parts + bool m_stripHeaders; // true if we're supposed to strip of message headers + bool m_stripHtml; // true if we're supposed to strip off HTML tags + bool m_pastMsgHeaders; // true if we've already skipped over the message headers + bool m_pastPartHeaders; // true if we've already skipped over the part headers + bool m_partIsHtml; // true if the Content-type header claims text/html + bool m_base64part; // true if the current part is in base64 + bool m_isMultipart; // true if the message is a multipart/* message + bool m_partIsText; // true if the current part is text/* + bool m_inMessageAttachment; // true if current part is message/* + + nsTArray<nsCString> m_boundaries; // The boundary strings to look for + nsCString m_partCharset; // The charset found in the part + + // See implementation for comments + int32_t ApplyTransformations (const nsCString &line, int32_t length, + bool &returnThisLine, nsCString &buf); + void SniffPossibleMIMEHeader (const nsCString &line); + static void StripHtml (nsCString &buf); + static void Base64Decode (nsCString &buf); +}; +#endif diff --git a/mailnews/base/search/public/nsMsgFilterCore.idl b/mailnews/base/search/public/nsMsgFilterCore.idl new file mode 100644 index 000000000..66ecb076a --- /dev/null +++ b/mailnews/base/search/public/nsMsgFilterCore.idl @@ -0,0 +1,63 @@ +/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsMsgSearchCore.idl" + +typedef long nsMsgFilterTypeType; + +[scriptable,uuid(b963a9c6-3a75-4d91-9f79-7186418d4d2d)] +interface nsMsgFilterType { + /* these longs are all actually of type nsMsgFilterTypeType */ + const long None = 0x00; + const long InboxRule = 0x01; + const long InboxJavaScript = 0x02; + const long Inbox = InboxRule | InboxJavaScript; + const long NewsRule = 0x04; + const long NewsJavaScript = 0x08; + const long News = NewsRule | NewsJavaScript; + const long Incoming = Inbox | News; + const long Manual = 0x10; + const long PostPlugin = 0x20; // After bayes filtering + const long PostOutgoing = 0x40; // After sending + const long Archive = 0x80; // Before archiving + const long All = Incoming | Manual; +}; + +typedef long nsMsgFilterMotionValue; + +typedef long nsMsgFilterIndex; + +typedef long nsMsgRuleActionType; + +[scriptable, uuid(7726FE79-AFA3-4a39-8292-733AEE288737)] +interface nsMsgFilterAction { + + // Custom Action. + const long Custom=-1; + /* if you change these, you need to update filter.properties, + look for filterActionX */ + /* these longs are all actually of type nsMsgFilterActionType */ + const long None=0; /* uninitialized state */ + const long MoveToFolder=1; + const long ChangePriority=2; + const long Delete=3; + const long MarkRead=4; + const long KillThread=5; + const long WatchThread=6; + const long MarkFlagged=7; + const long Label=8; + const long Reply=9; + const long Forward=10; + const long StopExecution=11; + const long DeleteFromPop3Server=12; + const long LeaveOnPop3Server=13; + const long JunkScore=14; + const long FetchBodyFromPop3Server=15; + const long CopyToFolder=16; + const long AddTag=17; + const long KillSubthread=18; + const long MarkUnread=19; +}; + diff --git a/mailnews/base/search/public/nsMsgResultElement.h b/mailnews/base/search/public/nsMsgResultElement.h new file mode 100644 index 000000000..384436299 --- /dev/null +++ b/mailnews/base/search/public/nsMsgResultElement.h @@ -0,0 +1,40 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __nsMsgResultElement_h +#define __nsMsgResultElement_h + +#include "nsMsgSearchCore.h" +#include "nsIMsgSearchAdapter.h" +#include "nsTArray.h" + +// nsMsgResultElement specifies a single search hit. + +//--------------------------------------------------------------------------- +// nsMsgResultElement is a list of attribute/value pairs which are used to +// represent a search hit without requiring a message header or server connection +//--------------------------------------------------------------------------- + +class nsMsgResultElement +{ +public: + nsMsgResultElement (nsIMsgSearchAdapter *); + virtual ~nsMsgResultElement (); + + static nsresult AssignValues (nsIMsgSearchValue *src, nsMsgSearchValue *dst); + nsresult GetValue (nsMsgSearchAttribValue, nsMsgSearchValue **) const; + nsresult AddValue (nsIMsgSearchValue*); + nsresult AddValue (nsMsgSearchValue*); + + nsresult GetPrettyName (nsMsgSearchValue**); + nsresult Open (void *window); + + nsTArray<nsCOMPtr<nsIMsgSearchValue> > m_valueList; + nsIMsgSearchAdapter *m_adapter; + +protected: +}; + +#endif diff --git a/mailnews/base/search/public/nsMsgSearchAdapter.h b/mailnews/base/search/public/nsMsgSearchAdapter.h new file mode 100644 index 000000000..0b1cd71da --- /dev/null +++ b/mailnews/base/search/public/nsMsgSearchAdapter.h @@ -0,0 +1,218 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef _nsMsgSearchAdapter_H_ +#define _nsMsgSearchAdapter_H_ + +#include "nsMsgSearchCore.h" +#include "nsCOMPtr.h" +#include "nsStringGlue.h" +#include "nsIMsgSearchAdapter.h" +#include "nsIMsgSearchValidityTable.h" +#include "nsIMsgSearchValidityManager.h" +#include "nsIMsgSearchTerm.h" +#include "nsINntpIncomingServer.h" + +class nsIMsgSearchScopeTerm; + +//----------------------------------------------------------------------------- +// These Adapter classes contain the smarts to convert search criteria from +// the canonical structures in msg_srch.h into whatever format is required +// by their protocol. +// +// There is a separate Adapter class for area (pop, imap, nntp, ldap) to contain +// the special smarts for that protocol. +//----------------------------------------------------------------------------- + +class nsMsgSearchAdapter : public nsIMsgSearchAdapter +{ +public: + nsMsgSearchAdapter (nsIMsgSearchScopeTerm*, nsISupportsArray *); + + NS_DECL_ISUPPORTS + NS_DECL_NSIMSGSEARCHADAPTER + + nsIMsgSearchScopeTerm *m_scope; + nsCOMPtr<nsISupportsArray> m_searchTerms; /* linked list of criteria terms */ + + bool m_abortCalled; + nsString m_defaultCharset; + bool m_forceAsciiSearch; + + static nsresult EncodeImap (char **ppEncoding, + nsISupportsArray *searchTerms, + const char16_t *srcCharset, + const char16_t *destCharset, + bool reallyDredd = false); + + static nsresult EncodeImapValue(char *encoding, const char *value, bool useQuotes, bool reallyDredd); + + static char *GetImapCharsetParam(const char16_t *destCharset); + static char16_t *EscapeSearchUrl (const char16_t *nntpCommand); + static char16_t *EscapeImapSearchProtocol(const char16_t *imapCommand); + static char16_t *EscapeQuoteImapSearchProtocol(const char16_t *imapCommand); + static char *UnEscapeSearchUrl (const char *commandSpecificData); + // This stuff lives in the base class because the IMAP search syntax + // is used by the Dredd SEARCH command as well as IMAP itself + static const char *m_kImapBefore; + static const char *m_kImapBody; + static const char *m_kImapCC; + static const char *m_kImapFrom; + static const char *m_kImapNot; + static const char *m_kImapOr; + static const char *m_kImapSince; + static const char *m_kImapSubject; + static const char *m_kImapTo; + static const char *m_kImapHeader; + static const char *m_kImapAnyText; + static const char *m_kImapKeyword; + static const char *m_kNntpKeywords; + static const char *m_kImapSentOn; + static const char *m_kImapSeen; + static const char *m_kImapAnswered; + static const char *m_kImapNotSeen; + static const char *m_kImapNotAnswered; + static const char *m_kImapCharset; + static const char *m_kImapUnDeleted; + static const char *m_kImapSizeSmaller; + static const char *m_kImapSizeLarger; + static const char *m_kImapNew; + static const char *m_kImapNotNew; + static const char *m_kImapFlagged; + static const char *m_kImapNotFlagged; +protected: + virtual ~nsMsgSearchAdapter(); + typedef enum _msg_TransformType + { + kOverwrite, /* "John Doe" -> "John*Doe", simple contains */ + kInsert, /* "John Doe" -> "John* Doe", name completion */ + kSurround /* "John Doe" -> "John* *Doe", advanced contains */ + } msg_TransformType; + + char *TransformSpacesToStars (const char *, msg_TransformType transformType); + nsresult OpenNewsResultInUnknownGroup (nsMsgResultElement*); + + static nsresult EncodeImapTerm (nsIMsgSearchTerm *, bool reallyDredd, const char16_t *srcCharset, const char16_t *destCharset, char **ppOutTerm); +}; + +//----------------------------------------------------------------------------- +// Validity checking for attrib/op pairs. We need to know what operations are +// legal in three places: +// 1. when the FE brings up the dialog box and needs to know how to build +// the menus and enable their items +// 2. when the FE fires off a search, we need to check their lists for +// correctness +// 3. for on-the-fly capability negotion e.g. with XSEARCH-capable news +// servers +//----------------------------------------------------------------------------- + +class nsMsgSearchValidityTable final : public nsIMsgSearchValidityTable +{ +public: + nsMsgSearchValidityTable (); + NS_DECL_NSIMSGSEARCHVALIDITYTABLE + NS_DECL_ISUPPORTS + +protected: + int m_numAvailAttribs; // number of rows with at least one available operator + typedef struct vtBits + { + uint16_t bitEnabled : 1; + uint16_t bitAvailable : 1; + uint16_t bitValidButNotShown : 1; + } vtBits; + vtBits m_table [nsMsgSearchAttrib::kNumMsgSearchAttributes][nsMsgSearchOp::kNumMsgSearchOperators]; +private: + ~nsMsgSearchValidityTable() {} + nsMsgSearchAttribValue m_defaultAttrib; +}; + +// Using getters and setters seems a little nicer then dumping the 2-D array +// syntax all over the code +#define CHECK_AO if (a < 0 || \ + a >= nsMsgSearchAttrib::kNumMsgSearchAttributes || \ + o < 0 || \ + o >= nsMsgSearchOp::kNumMsgSearchOperators) \ + return NS_ERROR_ILLEGAL_VALUE; +inline nsresult nsMsgSearchValidityTable::SetAvailable (int a, int o, bool b) +{ CHECK_AO; m_table [a][o].bitAvailable = b; return NS_OK;} +inline nsresult nsMsgSearchValidityTable::SetEnabled (int a, int o, bool b) +{ CHECK_AO; m_table [a][o].bitEnabled = b; return NS_OK; } +inline nsresult nsMsgSearchValidityTable::SetValidButNotShown (int a, int o, bool b) +{ CHECK_AO; m_table [a][o].bitValidButNotShown = b; return NS_OK;} + +inline nsresult nsMsgSearchValidityTable::GetAvailable (int a, int o, bool *aResult) +{ CHECK_AO; *aResult = m_table [a][o].bitAvailable; return NS_OK;} +inline nsresult nsMsgSearchValidityTable::GetEnabled (int a, int o, bool *aResult) +{ CHECK_AO; *aResult = m_table [a][o].bitEnabled; return NS_OK;} +inline nsresult nsMsgSearchValidityTable::GetValidButNotShown (int a, int o, bool *aResult) +{ CHECK_AO; *aResult = m_table [a][o].bitValidButNotShown; return NS_OK;} +#undef CHECK_AO + +class nsMsgSearchValidityManager : public nsIMsgSearchValidityManager +{ +public: + nsMsgSearchValidityManager (); + +protected: + virtual ~nsMsgSearchValidityManager (); + +public: + NS_DECL_NSIMSGSEARCHVALIDITYMANAGER + NS_DECL_ISUPPORTS + + nsresult GetTable (int, nsMsgSearchValidityTable**); + +protected: + + // There's one global validity manager that everyone uses. You *could* do + // this with static members of the adapter classes, but having a dedicated + // object makes cleanup of these tables (at shutdown-time) automagic. + + nsCOMPtr<nsIMsgSearchValidityTable> m_offlineMailTable; + nsCOMPtr<nsIMsgSearchValidityTable> m_offlineMailFilterTable; + nsCOMPtr<nsIMsgSearchValidityTable> m_onlineMailTable; + nsCOMPtr<nsIMsgSearchValidityTable> m_onlineMailFilterTable; + nsCOMPtr<nsIMsgSearchValidityTable> m_onlineManualFilterTable; + + nsCOMPtr<nsIMsgSearchValidityTable> m_newsTable; // online news + + // Local news tables, used for local news searching or offline. + nsCOMPtr<nsIMsgSearchValidityTable> m_localNewsTable; // base table + nsCOMPtr<nsIMsgSearchValidityTable> m_localNewsJunkTable; // base + junk + nsCOMPtr<nsIMsgSearchValidityTable> m_localNewsBodyTable; // base + body + nsCOMPtr<nsIMsgSearchValidityTable> m_localNewsJunkBodyTable; // base + junk + body + nsCOMPtr<nsIMsgSearchValidityTable> m_ldapTable; + nsCOMPtr<nsIMsgSearchValidityTable> m_ldapAndTable; + nsCOMPtr<nsIMsgSearchValidityTable> m_localABTable; + nsCOMPtr<nsIMsgSearchValidityTable> m_localABAndTable; + nsCOMPtr<nsIMsgSearchValidityTable> m_newsFilterTable; + + nsresult NewTable (nsIMsgSearchValidityTable **); + + nsresult InitOfflineMailTable(); + nsresult InitOfflineMailFilterTable(); + nsresult InitOnlineMailTable(); + nsresult InitOnlineMailFilterTable(); + nsresult InitOnlineManualFilterTable(); + nsresult InitNewsTable(); + nsresult InitLocalNewsTable(); + nsresult InitLocalNewsJunkTable(); + nsresult InitLocalNewsBodyTable(); + nsresult InitLocalNewsJunkBodyTable(); + nsresult InitNewsFilterTable(); + + //set the custom headers in the table, changes whenever "mailnews.customHeaders" pref changes. + nsresult SetOtherHeadersInTable(nsIMsgSearchValidityTable *table, const char *customHeaders); + + nsresult InitLdapTable(); + nsresult InitLdapAndTable(); + nsresult InitLocalABTable(); + nsresult InitLocalABAndTable(); + nsresult SetUpABTable(nsIMsgSearchValidityTable *aTable, bool isOrTable); + nsresult EnableDirectoryAttribute(nsIMsgSearchValidityTable *table, nsMsgSearchAttribValue aSearchAttrib); +}; + +#endif diff --git a/mailnews/base/search/public/nsMsgSearchBoolExpression.h b/mailnews/base/search/public/nsMsgSearchBoolExpression.h new file mode 100644 index 000000000..c65e5c24a --- /dev/null +++ b/mailnews/base/search/public/nsMsgSearchBoolExpression.h @@ -0,0 +1,107 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsMsgSearchCore.h" + +#ifndef __nsMsgSearchBoolExpression_h +#define __nsMsgSearchBoolExpression_h + +//----------------------------------------------------------------------------- +// nsMsgSearchBoolExpression is a class added to provide AND/OR terms in search queries. +// A nsMsgSearchBoolExpression contains either a search term or two nsMsgSearchBoolExpressions and +// a boolean operator. +// I (mscott) am placing it here for now.... +//----------------------------------------------------------------------------- + +/* CBoolExpression --> encapsulates one or more search terms by internally + representing the search terms and their boolean operators as a binary + expression tree. Each node in the tree consists of either + (1) a boolean operator and two nsMsgSearchBoolExpressions or + (2) if the node is a leaf node then it contains a search term. + With each search term that is part of the expression we may also keep + a character string. The character + string is used to store the IMAP/NNTP encoding of the search term. This + makes generating a search encoding (for online) easier. + + For IMAP/NNTP: nsMsgSearchBoolExpression has/assumes knowledge about how + AND and OR search terms are combined according to IMAP4 and NNTP protocol. + That is the only piece of IMAP/NNTP knowledge it is aware of. + + Order of Evaluation: Okay, the way in which the boolean expression tree + is put together directly effects the order of evaluation. We currently + support left to right evaluation. + Supporting other order of evaluations involves adding new internal add + term methods. + */ + +class nsMsgSearchBoolExpression +{ +public: + + // create a leaf node expression + nsMsgSearchBoolExpression(nsIMsgSearchTerm * aNewTerm, + char * aEncodingString = NULL); + + // create a non-leaf node expression containing 2 expressions + // and a boolean operator + nsMsgSearchBoolExpression(nsMsgSearchBoolExpression *, + nsMsgSearchBoolExpression *, + nsMsgSearchBooleanOperator boolOp); + + nsMsgSearchBoolExpression(); + ~nsMsgSearchBoolExpression(); // recursively destroys all sub + // expressions as well + + // accessors + + // Offline + static nsMsgSearchBoolExpression * AddSearchTerm (nsMsgSearchBoolExpression * aOrigExpr, nsIMsgSearchTerm * aNewTerm, char * aEncodingStr); // IMAP/NNTP + static nsMsgSearchBoolExpression * AddExpressionTree(nsMsgSearchBoolExpression * aOrigExpr, nsMsgSearchBoolExpression * aExpression, bool aBoolOp); + + // parses the expression tree and all + // expressions underneath this node to + // determine if the end result is true or false. + bool OfflineEvaluate(nsIMsgDBHdr *msgToMatch, + const char *defaultCharset, nsIMsgSearchScopeTerm *scope, + nsIMsgDatabase *db, const char *headers, uint32_t headerSize, + bool Filtering); + + // assuming the expression is for online + // searches, determine the length of the + // resulting IMAP/NNTP encoding string + int32_t CalcEncodeStrSize(); + + // fills pre-allocated + // memory in buffer with + // the IMAP/NNTP encoding for the expression + void GenerateEncodeStr(nsCString * buffer); + + // if we are not a leaf node, then we have two other expressions + // and a boolean operator + nsMsgSearchBoolExpression * m_leftChild; + nsMsgSearchBoolExpression * m_rightChild; + nsMsgSearchBooleanOperator m_boolOp; + +protected: + // if we are a leaf node, all we have is a search term + + nsIMsgSearchTerm * m_term; + + // store IMAP/NNTP encoding for the search term if applicable + nsCString m_encodingStr; + + // internal methods + + // the idea is to separate the public interface for adding terms to + // the expression tree from the order of evaluation which influences + // how we internally construct the tree. Right now, we are supporting + // left to right evaluation so the tree is constructed to represent + // that by calling leftToRightAddTerm. If future forms of evaluation + // need to be supported, add new methods here for proper tree construction. + nsMsgSearchBoolExpression * leftToRightAddTerm(nsIMsgSearchTerm * newTerm, + char * encodingStr); +}; + +#endif diff --git a/mailnews/base/search/public/nsMsgSearchCore.idl b/mailnews/base/search/public/nsMsgSearchCore.idl new file mode 100644 index 000000000..6431aa8c3 --- /dev/null +++ b/mailnews/base/search/public/nsMsgSearchCore.idl @@ -0,0 +1,222 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsISupports.idl" +#include "MailNewsTypes2.idl" + +interface nsIMsgFolder; + +interface nsIMsgDatabase; +interface nsIMsgDBHdr; + +[scriptable, uuid(6e893e59-af98-4f62-a326-0f00f32147cd)] + +interface nsMsgSearchScope { + const nsMsgSearchScopeValue offlineMail = 0; + const nsMsgSearchScopeValue offlineMailFilter = 1; + const nsMsgSearchScopeValue onlineMail = 2; + const nsMsgSearchScopeValue onlineMailFilter = 3; + /// offline news, base table, no body or junk + const nsMsgSearchScopeValue localNews = 4; + const nsMsgSearchScopeValue news = 5; + const nsMsgSearchScopeValue newsEx = 6; + const nsMsgSearchScopeValue LDAP = 7; + const nsMsgSearchScopeValue LocalAB = 8; + const nsMsgSearchScopeValue allSearchableGroups = 9; + const nsMsgSearchScopeValue newsFilter = 10; + const nsMsgSearchScopeValue LocalABAnd = 11; + const nsMsgSearchScopeValue LDAPAnd = 12; + // IMAP and NEWS, searched using local headers + const nsMsgSearchScopeValue onlineManual = 13; + /// local news + junk + const nsMsgSearchScopeValue localNewsJunk = 14; + /// local news + body + const nsMsgSearchScopeValue localNewsBody = 15; + /// local news + junk + body + const nsMsgSearchScopeValue localNewsJunkBody = 16; +}; + +typedef long nsMsgSearchAttribValue; + +/** + * Definitions of search attribute types. The numerical order + * from here will also be used to determine the order that the + * attributes display in the filter editor. + */ +[scriptable, uuid(a83ca7e8-4591-4111-8fb8-fd76ac73c866)] +interface nsMsgSearchAttrib { + const nsMsgSearchAttribValue Custom = -2; /* a custom term, see nsIMsgSearchCustomTerm */ + const nsMsgSearchAttribValue Default = -1; + const nsMsgSearchAttribValue Subject = 0; /* mail and news */ + const nsMsgSearchAttribValue Sender = 1; + const nsMsgSearchAttribValue Body = 2; + const nsMsgSearchAttribValue Date = 3; + + const nsMsgSearchAttribValue Priority = 4; /* mail only */ + const nsMsgSearchAttribValue MsgStatus = 5; + const nsMsgSearchAttribValue To = 6; + const nsMsgSearchAttribValue CC = 7; + const nsMsgSearchAttribValue ToOrCC = 8; + const nsMsgSearchAttribValue AllAddresses = 9; + + const nsMsgSearchAttribValue Location = 10; /* result list only */ + const nsMsgSearchAttribValue MessageKey = 11; /* message result elems */ + const nsMsgSearchAttribValue AgeInDays = 12; + const nsMsgSearchAttribValue FolderInfo = 13; /* for "view thread context" from result */ + const nsMsgSearchAttribValue Size = 14; + const nsMsgSearchAttribValue AnyText = 15; + const nsMsgSearchAttribValue Keywords = 16; // keywords are the internal representation of tags. + + const nsMsgSearchAttribValue Name = 17; + const nsMsgSearchAttribValue DisplayName = 18; + const nsMsgSearchAttribValue Nickname = 19; + const nsMsgSearchAttribValue ScreenName = 20; + const nsMsgSearchAttribValue Email = 21; + const nsMsgSearchAttribValue AdditionalEmail = 22; + const nsMsgSearchAttribValue PhoneNumber = 23; + const nsMsgSearchAttribValue WorkPhone = 24; + const nsMsgSearchAttribValue HomePhone = 25; + const nsMsgSearchAttribValue Fax = 26; + const nsMsgSearchAttribValue Pager = 27; + const nsMsgSearchAttribValue Mobile = 28; + const nsMsgSearchAttribValue City = 29; + const nsMsgSearchAttribValue Street = 30; + const nsMsgSearchAttribValue Title = 31; + const nsMsgSearchAttribValue Organization = 32; + const nsMsgSearchAttribValue Department = 33; + + // 34 - 43, reserved for ab / LDAP; + const nsMsgSearchAttribValue HasAttachmentStatus = 44; + const nsMsgSearchAttribValue JunkStatus = 45; + const nsMsgSearchAttribValue JunkPercent = 46; + const nsMsgSearchAttribValue JunkScoreOrigin = 47; + const nsMsgSearchAttribValue Label = 48; /* mail only...can search by label */ + const nsMsgSearchAttribValue HdrProperty = 49; // uses nsIMsgSearchTerm::hdrProperty + const nsMsgSearchAttribValue FolderFlag = 50; // uses nsIMsgSearchTerm::status + const nsMsgSearchAttribValue Uint32HdrProperty = 51; // uses nsIMsgSearchTerm::hdrProperty + + // 52 is for showing customize - in ui headers start from 53 onwards up until 99. + + /** OtherHeader MUST ALWAYS BE LAST attribute since + * we can have an arbitrary # of these. The number can be changed, + * however, because we never persist AttribValues as integers. + */ + const nsMsgSearchAttribValue OtherHeader = 52; + // must be last attribute + const nsMsgSearchAttribValue kNumMsgSearchAttributes = 100; +}; + +typedef long nsMsgSearchOpValue; + +[scriptable, uuid(9160b196-6fcb-4eba-aaaf-6c806c4ee420)] +interface nsMsgSearchOp { + const nsMsgSearchOpValue Contains = 0; /* for text attributes */ + const nsMsgSearchOpValue DoesntContain = 1; + const nsMsgSearchOpValue Is = 2; /* is and isn't also apply to some non-text attrs */ + const nsMsgSearchOpValue Isnt = 3; + const nsMsgSearchOpValue IsEmpty = 4; + + const nsMsgSearchOpValue IsBefore = 5; /* for date attributes */ + const nsMsgSearchOpValue IsAfter = 6; + + const nsMsgSearchOpValue IsHigherThan = 7; /* for priority. Is also applies */ + const nsMsgSearchOpValue IsLowerThan = 8; + + const nsMsgSearchOpValue BeginsWith = 9; + const nsMsgSearchOpValue EndsWith = 10; + + const nsMsgSearchOpValue SoundsLike = 11; /* for LDAP phoenetic matching */ + const nsMsgSearchOpValue LdapDwim = 12; /* Do What I Mean for simple search */ + + const nsMsgSearchOpValue IsGreaterThan = 13; + const nsMsgSearchOpValue IsLessThan = 14; + + const nsMsgSearchOpValue NameCompletion = 15; /* Name Completion operator...as the name implies =) */ + const nsMsgSearchOpValue IsInAB = 16; + const nsMsgSearchOpValue IsntInAB = 17; + const nsMsgSearchOpValue IsntEmpty = 18; /* primarily for tags */ + const nsMsgSearchOpValue Matches = 19; /* generic term for use by custom terms */ + const nsMsgSearchOpValue DoesntMatch = 20; /* generic term for use by custom terms */ + const nsMsgSearchOpValue kNumMsgSearchOperators = 21; /* must be last operator */ +}; + +typedef long nsMsgSearchWidgetValue; + +/* FEs use this to help build the search dialog box */ +[scriptable,uuid(903dd2e8-304e-11d3-92e6-00a0c900d445)] +interface nsMsgSearchWidget { + const nsMsgSearchWidgetValue Text = 0; + const nsMsgSearchWidgetValue Date = 1; + const nsMsgSearchWidgetValue Menu = 2; + const nsMsgSearchWidgetValue Int = 3; /* added to account for age in days which requires an integer field */ + const nsMsgSearchWidgetValue None = 4; +}; + +typedef long nsMsgSearchTypeValue; + + +/* Used to specify type of search to be performed */ +[scriptable,uuid(964b7f32-304e-11d3-ae13-00a0c900d445)] +interface nsMsgSearchType { + const nsMsgSearchTypeValue None = 0; + const nsMsgSearchTypeValue RootDSE = 1; + const nsMsgSearchTypeValue Normal = 2; + const nsMsgSearchTypeValue LdapVLV = 3; + const nsMsgSearchTypeValue NameCompletion = 4; +}; + +typedef long nsMsgSearchBooleanOperator; + +[scriptable, uuid(a37f3f4a-304e-11d3-8f94-00a0c900d445)] +interface nsMsgSearchBooleanOp { + const nsMsgSearchBooleanOperator BooleanOR = 0; + const nsMsgSearchBooleanOperator BooleanAND = 1; +}; + +/* Use this to specify the value of a search term */ + +[ptr] native nsMsgSearchValue(nsMsgSearchValue); + +%{C++ +#include "nsStringGlue.h" + +typedef struct nsMsgSearchValue +{ + nsMsgSearchAttribValue attribute; + union + { + nsMsgPriorityValue priority; + PRTime date; + uint32_t msgStatus; /* see MSG_FLAG in msgcom.h */ + uint32_t size; + nsMsgKey key; + int32_t age; /* in days */ + nsIMsgFolder *folder; + nsMsgLabelValue label; + uint32_t junkStatus; + uint32_t junkPercent; + } u; + char *string; + nsString utf16String; +} nsMsgSearchValue; +%} + +[ptr] native nsMsgSearchTerm(nsMsgSearchTerm); + +// Please note the ! at the start of this macro, which means the macro +// needs to enumerate the non-string attributes. +%{C++ +#define IS_STRING_ATTRIBUTE(_a) \ +(!(_a == nsMsgSearchAttrib::Priority || _a == nsMsgSearchAttrib::Date || \ + _a == nsMsgSearchAttrib::MsgStatus || _a == nsMsgSearchAttrib::MessageKey || \ + _a == nsMsgSearchAttrib::Size || _a == nsMsgSearchAttrib::AgeInDays || \ + _a == nsMsgSearchAttrib::FolderInfo || _a == nsMsgSearchAttrib::Location || \ + _a == nsMsgSearchAttrib::Label || _a == nsMsgSearchAttrib::JunkStatus || \ + _a == nsMsgSearchAttrib::FolderFlag || _a == nsMsgSearchAttrib::Uint32HdrProperty || \ + _a == nsMsgSearchAttrib::JunkPercent || _a == nsMsgSearchAttrib::HasAttachmentStatus)) +%} + +[ptr] native nsSearchMenuItem(nsSearchMenuItem); + diff --git a/mailnews/base/search/public/nsMsgSearchScopeTerm.h b/mailnews/base/search/public/nsMsgSearchScopeTerm.h new file mode 100644 index 000000000..74afd8d19 --- /dev/null +++ b/mailnews/base/search/public/nsMsgSearchScopeTerm.h @@ -0,0 +1,45 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef __nsMsgSearchScopeTerm_h +#define __nsMsgSearchScopeTerm_h + +#include "nsMsgSearchCore.h" +#include "nsMsgSearchScopeTerm.h" +#include "nsIMsgSearchAdapter.h" +#include "nsIMsgFolder.h" +#include "nsIMsgSearchAdapter.h" +#include "nsIMsgSearchSession.h" +#include "nsCOMPtr.h" +#include "nsIWeakReference.h" +#include "nsIWeakReferenceUtils.h" + +class nsMsgSearchScopeTerm : public nsIMsgSearchScopeTerm +{ +public: + nsMsgSearchScopeTerm (nsIMsgSearchSession *, nsMsgSearchScopeValue, nsIMsgFolder *); + nsMsgSearchScopeTerm (); + + NS_DECL_ISUPPORTS + NS_DECL_NSIMSGSEARCHSCOPETERM + + nsresult TimeSlice (bool *aDone); + nsresult InitializeAdapter (nsISupportsArray *termList); + + char *GetStatusBarName (); + + nsMsgSearchScopeValue m_attribute; + char *m_name; + nsCOMPtr <nsIMsgFolder> m_folder; + nsCOMPtr <nsIMsgSearchAdapter> m_adapter; + nsCOMPtr <nsIInputStream> m_inputStream; // for message bodies + nsWeakPtr m_searchSession; + bool m_searchServer; + +private: + virtual ~nsMsgSearchScopeTerm(); +}; + +#endif diff --git a/mailnews/base/search/public/nsMsgSearchTerm.h b/mailnews/base/search/public/nsMsgSearchTerm.h new file mode 100644 index 000000000..ffcdc9539 --- /dev/null +++ b/mailnews/base/search/public/nsMsgSearchTerm.h @@ -0,0 +1,85 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + + +#ifndef __nsMsgSearchTerm_h +#define __nsMsgSearchTerm_h +//--------------------------------------------------------------------------- +// nsMsgSearchTerm specifies one criterion, e.g. name contains phil +//--------------------------------------------------------------------------- +#include "nsIMsgSearchSession.h" +#include "nsIMsgSearchScopeTerm.h" +#include "nsIMsgSearchTerm.h" +#include "nsIMsgSearchCustomTerm.h" + +// needed to search for addresses in address books +#include "nsIAbDirectory.h" + +#define EMPTY_MESSAGE_LINE(buf) (buf[0] == '\r' || buf[0] == '\n' || buf[0] == '\0') + +class nsMsgSearchTerm : public nsIMsgSearchTerm +{ +public: + nsMsgSearchTerm(); + nsMsgSearchTerm (nsMsgSearchAttribValue, nsMsgSearchOpValue, nsIMsgSearchValue *, nsMsgSearchBooleanOperator, const char * arbitraryHeader); + + NS_DECL_ISUPPORTS + NS_DECL_NSIMSGSEARCHTERM + + nsresult DeStream (char *, int16_t length); + nsresult DeStreamNew (char *, int16_t length); + + nsresult GetLocalTimes (PRTime, PRTime, PRExplodedTime &, PRExplodedTime &); + + bool IsBooleanOpAND() { return m_booleanOp == nsMsgSearchBooleanOp::BooleanAND ? true : false;} + nsMsgSearchBooleanOperator GetBooleanOp() {return m_booleanOp;} + // maybe should return nsString & ?? + const char * GetArbitraryHeader() {return m_arbitraryHeader.get();} + + static char * EscapeQuotesInStr(const char *str); + + nsMsgSearchAttribValue m_attribute; + nsMsgSearchOpValue m_operator; + nsMsgSearchValue m_value; + + // boolean operator to be applied to this search term and the search term which precedes it. + nsMsgSearchBooleanOperator m_booleanOp; + + // user specified string for the name of the arbitrary header to be used in the search + // only has a value when m_attribute = OtherHeader!!!! + nsCString m_arbitraryHeader; + + // db hdr property name to use - used when m_attribute = HdrProperty. + nsCString m_hdrProperty; + bool m_matchAll; // does this term match all headers? + nsCString m_customId; // id of custom search term + +protected: + virtual ~nsMsgSearchTerm(); + + nsresult MatchString(const nsACString &stringToMatch, const char *charset, + bool *pResult); + nsresult MatchString(const nsAString &stringToMatch, bool *pResult); + nsresult OutputValue(nsCString &outputStr); + nsresult ParseAttribute(char *inStream, nsMsgSearchAttribValue *attrib); + nsresult ParseOperator(char *inStream, nsMsgSearchOpValue *value); + nsresult ParseValue(char *inStream); + /** + * Switch a string to lower case, except for special database rows + * that are not headers, but could be headers + * + * @param aValue the string to switch + */ + void ToLowerCaseExceptSpecials(nsACString &aValue); + nsresult InitializeAddressBook(); + nsresult MatchInAddressBook(const nsAString &aAddress, bool *pResult); + // fields used by search in address book + nsCOMPtr <nsIAbDirectory> mDirectory; + + bool mBeginsGrouping; + bool mEndsGrouping; +}; + +#endif |