From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- comm/mailnews/search/public/moz.build | 37 +++ comm/mailnews/search/public/nsIMsgFilter.idl | 124 ++++++++ .../search/public/nsIMsgFilterCustomAction.idl | 88 ++++++ .../search/public/nsIMsgFilterHitNotify.idl | 26 ++ comm/mailnews/search/public/nsIMsgFilterList.idl | 115 +++++++ comm/mailnews/search/public/nsIMsgFilterPlugin.idl | 331 +++++++++++++++++++++ .../mailnews/search/public/nsIMsgFilterService.idl | 102 +++++++ .../search/public/nsIMsgOperationListener.idl | 17 ++ .../mailnews/search/public/nsIMsgSearchAdapter.idl | 41 +++ .../search/public/nsIMsgSearchCustomTerm.idl | 75 +++++ comm/mailnews/search/public/nsIMsgSearchNotify.idl | 30 ++ .../search/public/nsIMsgSearchScopeTerm.idl | 19 ++ .../mailnews/search/public/nsIMsgSearchSession.idl | 130 ++++++++ comm/mailnews/search/public/nsIMsgSearchTerm.idl | 153 ++++++++++ .../search/public/nsIMsgSearchValidityManager.idl | 26 ++ .../search/public/nsIMsgSearchValidityTable.idl | 32 ++ comm/mailnews/search/public/nsIMsgSearchValue.idl | 35 +++ comm/mailnews/search/public/nsIMsgTraitService.idl | 182 +++++++++++ comm/mailnews/search/public/nsMsgBodyHandler.h | 110 +++++++ comm/mailnews/search/public/nsMsgFilterCore.idl | 62 ++++ comm/mailnews/search/public/nsMsgResultElement.h | 40 +++ comm/mailnews/search/public/nsMsgSearchAdapter.h | 242 +++++++++++++++ .../search/public/nsMsgSearchBoolExpression.h | 110 +++++++ comm/mailnews/search/public/nsMsgSearchCore.idl | 206 +++++++++++++ comm/mailnews/search/public/nsMsgSearchScopeTerm.h | 44 +++ comm/mailnews/search/public/nsMsgSearchTerm.h | 89 ++++++ 26 files changed, 2466 insertions(+) create mode 100644 comm/mailnews/search/public/moz.build create mode 100644 comm/mailnews/search/public/nsIMsgFilter.idl create mode 100644 comm/mailnews/search/public/nsIMsgFilterCustomAction.idl create mode 100644 comm/mailnews/search/public/nsIMsgFilterHitNotify.idl create mode 100644 comm/mailnews/search/public/nsIMsgFilterList.idl create mode 100644 comm/mailnews/search/public/nsIMsgFilterPlugin.idl create mode 100644 comm/mailnews/search/public/nsIMsgFilterService.idl create mode 100644 comm/mailnews/search/public/nsIMsgOperationListener.idl create mode 100644 comm/mailnews/search/public/nsIMsgSearchAdapter.idl create mode 100644 comm/mailnews/search/public/nsIMsgSearchCustomTerm.idl create mode 100644 comm/mailnews/search/public/nsIMsgSearchNotify.idl create mode 100644 comm/mailnews/search/public/nsIMsgSearchScopeTerm.idl create mode 100644 comm/mailnews/search/public/nsIMsgSearchSession.idl create mode 100644 comm/mailnews/search/public/nsIMsgSearchTerm.idl create mode 100644 comm/mailnews/search/public/nsIMsgSearchValidityManager.idl create mode 100644 comm/mailnews/search/public/nsIMsgSearchValidityTable.idl create mode 100644 comm/mailnews/search/public/nsIMsgSearchValue.idl create mode 100644 comm/mailnews/search/public/nsIMsgTraitService.idl create mode 100644 comm/mailnews/search/public/nsMsgBodyHandler.h create mode 100644 comm/mailnews/search/public/nsMsgFilterCore.idl create mode 100644 comm/mailnews/search/public/nsMsgResultElement.h create mode 100644 comm/mailnews/search/public/nsMsgSearchAdapter.h create mode 100644 comm/mailnews/search/public/nsMsgSearchBoolExpression.h create mode 100644 comm/mailnews/search/public/nsMsgSearchCore.idl create mode 100644 comm/mailnews/search/public/nsMsgSearchScopeTerm.h create mode 100644 comm/mailnews/search/public/nsMsgSearchTerm.h (limited to 'comm/mailnews/search/public') diff --git a/comm/mailnews/search/public/moz.build b/comm/mailnews/search/public/moz.build new file mode 100644 index 0000000000..39a41a1d2a --- /dev/null +++ b/comm/mailnews/search/public/moz.build @@ -0,0 +1,37 @@ +# 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/comm/mailnews/search/public/nsIMsgFilter.idl b/comm/mailnews/search/public/nsIMsgFilter.idl new file mode 100644 index 0000000000..6cf65c774e --- /dev/null +++ b/comm/mailnews/search/public/nsIMsgFilter.idl @@ -0,0 +1,124 @@ +/* -*- 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 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 AUTF8String targetFolderUri; + + 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 Array searchTerms; + + attribute nsIMsgSearchScopeTerm scope; + + boolean MatchHdr(in nsIMsgDBHdr msgHdr, in nsIMsgFolder folder, + in nsIMsgDatabase db, + in ACString headers); // null-separated list of headers + + + /* + * 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 AUTF8String 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 Array sortedActionList; + + void SaveToTextFile(in nsIOutputStream aStream); +}; diff --git a/comm/mailnews/search/public/nsIMsgFilterCustomAction.idl b/comm/mailnews/search/public/nsIMsgFilterCustomAction.idl new file mode 100644 index 0000000000..6e0f15cb09 --- /dev/null +++ b/comm/mailnews/search/public/nsIMsgFilterCustomAction.idl @@ -0,0 +1,88 @@ +/* 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 nsIMsgCopyServiceListener; +interface nsIMsgWindow; +interface nsIMsgDBHdr; + +/** + * 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 applyAction 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 applyAction(in Array msgHdrs, + 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/comm/mailnews/search/public/nsIMsgFilterHitNotify.idl b/comm/mailnews/search/public/nsIMsgFilterHitNotify.idl new file mode 100644 index 0000000000..c0bea47db1 --- /dev/null +++ b/comm/mailnews/search/public/nsIMsgFilterHitNotify.idl @@ -0,0 +1,26 @@ +/* -*- 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/comm/mailnews/search/public/nsIMsgFilterList.idl b/comm/mailnews/search/public/nsIMsgFilterList.idl new file mode 100644 index 0000000000..fa294d5063 --- /dev/null +++ b/comm/mailnews/search/public/nsIMsgFilterList.idl @@ -0,0 +1,115 @@ +/* -*- 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; + + /// Unique text identifier of this filter list. + readonly attribute ACString listId; + 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); + + 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 initially + // (such as the filter list dialog) + attribute nsIFile defaultFile; + void saveToDefaultFile(); + + void applyFiltersToHdr(in nsMsgFilterTypeType filterType, + in nsIMsgDBHdr msgHdr, + in nsIMsgFolder folder, + in nsIMsgDatabase db, + in ACString headers, // null-separated list of headers + 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 AUTF8String oldUri, in AUTF8String newUri, in boolean caseInsensitive); + + /** + * Turn filter logging on or off. Turning logging off will close any + * currently-open open logfile. + */ + attribute boolean loggingEnabled; + /** + * The log will be written via logStream. This may be null if + * loggingEnabled is false or if there is some problem with the logging. + */ + attribute nsIOutputStream logStream; + readonly attribute ACString logURL; + void clearLog(); + void flushLogIfNecessary(); + /** + * Push a message to the filter log file, adding a timestamp. + * + * @param message The message text to log. + * @param filter Optional filter object that reports the message. + */ + void logFilterMessage(in AString message, [optional] in nsIMsgFilter filter); +}; + + +/* these longs are all actually of type nsMsgFilterMotionValue */ +[scriptable, uuid(d067b528-304e-11d3-a0e1-00a0c900d445)] +interface nsMsgFilterMotion : nsISupports { + const long up = 0; + const long down = 1; +}; diff --git a/comm/mailnews/search/public/nsIMsgFilterPlugin.idl b/comm/mailnews/search/public/nsIMsgFilterPlugin.idl new file mode 100644 index 0000000000..93934a364a --- /dev/null +++ b/comm/mailnews/search/public/nsIMsgFilterPlugin.idl @@ -0,0 +1,331 @@ +/* -*- 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 AUTF8String 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 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 AUTF8String aMsgURI, + in Array aTraits, + in Array 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 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 AUTF8String aMsgUri, + in unsigned long aProTrait, + in Array tokenStrings, + in Array tokenPercents, + in Array 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 AUTF8String aMsgURI, in nsIMsgWindow aMsgWindow, + in nsIJunkMailClassificationListener aListener); + + void classifyMessages(in Array 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 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 AUTF8String aMsgURI, + in Array aProTraits, + in Array 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 aMsgURIs array of URIs of the messages to be evaluated + * @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 Array aMsgURIs, + in Array aProTraits, + in Array 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 AUTF8String 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 aOldTraits array of trait IDs of the old + * message classification(s), if any + * @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 AUTF8String aMsgURI, + in Array aOldTraits, + in Array 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 AUTF8String 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. + * Uses the parallel arrays aFromTraits and 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 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 aFromTraits array of trait ids used in aFile. If aFile contains + * trait ids that are not in this array, they are not + * remapped, but assumed 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 Array aFromTraits, + [optional] in Array 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/comm/mailnews/search/public/nsIMsgFilterService.idl b/comm/mailnews/search/public/nsIMsgFilterService.idl new file mode 100644 index 0000000000..439dd40f93 --- /dev/null +++ b/comm/mailnews/search/public/nsIMsgFilterService.idl @@ -0,0 +1,102 @@ +/* -*- 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 nsIFile; +interface nsIMsgFolder; +interface nsIMsgSearchCustomTerm; +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 Array 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 Array 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 an array of nsIMsgFilterCustomAction objects + */ + Array 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 an array of nsIMsgSearchCustomTerm objects + */ + Array 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); + + /** + * Translate the filter type flag into human readable type names. + * In case of multiple flag they are delimited by '&'. + * + * @param filterType nsMsgFilterType flags of filter type + * + * @return A string describing the filter type. + */ + ACString filterTypeName(in nsMsgFilterTypeType filterType); +}; diff --git a/comm/mailnews/search/public/nsIMsgOperationListener.idl b/comm/mailnews/search/public/nsIMsgOperationListener.idl new file mode 100644 index 0000000000..30751cd5c3 --- /dev/null +++ b/comm/mailnews/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/comm/mailnews/search/public/nsIMsgSearchAdapter.idl b/comm/mailnews/search/public/nsIMsgSearchAdapter.idl new file mode 100644 index 0000000000..9784fdda79 --- /dev/null +++ b/comm/mailnews/search/public/nsIMsgSearchAdapter.idl @@ -0,0 +1,41 @@ +/* -*- 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/comm/mailnews/search/public/nsIMsgSearchCustomTerm.idl b/comm/mailnews/search/public/nsIMsgSearchCustomTerm.idl new file mode 100644 index 0000000000..b2e3c024cd --- /dev/null +++ b/comm/mailnews/search/public/nsIMsgSearchCustomTerm.idl @@ -0,0 +1,75 @@ +/* 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) + * + * @return array of operators + */ + Array getAvailableOperators(in nsMsgSearchScopeValue scope); + + /** + * 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/comm/mailnews/search/public/nsIMsgSearchNotify.idl b/comm/mailnews/search/public/nsIMsgSearchNotify.idl new file mode 100644 index 0000000000..1e3493ad83 --- /dev/null +++ b/comm/mailnews/search/public/nsIMsgSearchNotify.idl @@ -0,0 +1,30 @@ +/* -*- 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/comm/mailnews/search/public/nsIMsgSearchScopeTerm.idl b/comm/mailnews/search/public/nsIMsgSearchScopeTerm.idl new file mode 100644 index 0000000000..63a130d9ea --- /dev/null +++ b/comm/mailnews/search/public/nsIMsgSearchScopeTerm.idl @@ -0,0 +1,19 @@ +/* -*- 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/comm/mailnews/search/public/nsIMsgSearchSession.idl b/comm/mailnews/search/public/nsIMsgSearchSession.idl new file mode 100644 index 0000000000..024ce829b2 --- /dev/null +++ b/comm/mailnews/search/public/nsIMsgSearchSession.idl @@ -0,0 +1,130 @@ +/* -*- 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 nsIMsgDatabase; +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); + + attribute Array 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 every time 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(); + + 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/comm/mailnews/search/public/nsIMsgSearchTerm.idl b/comm/mailnews/search/public/nsIMsgSearchTerm.idl new file mode 100644 index 0000000000..5724ba1c1a --- /dev/null +++ b/comm/mailnews/search/public/nsIMsgSearchTerm.idl @@ -0,0 +1,153 @@ +/* -*- 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 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. + * @param aMsg The nsIMsgDBHdr of the message + * @param aDb The message database containing aMsg + * @param aHeaders A null-separated list of message headers. + * @param aForFilters Whether this is a filter or a search operation. + */ + boolean matchArbitraryHeader(in nsIMsgSearchScopeTerm aScopeTerm, + in unsigned long aLength, + in string aCharset, + in boolean aCharsetOverride, + in nsIMsgDBHdr aMsg, + in nsIMsgDatabase aDb, + in ACString aHeaders, + 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/comm/mailnews/search/public/nsIMsgSearchValidityManager.idl b/comm/mailnews/search/public/nsIMsgSearchValidityManager.idl new file mode 100644 index 0000000000..dbc7958bd8 --- /dev/null +++ b/comm/mailnews/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/comm/mailnews/search/public/nsIMsgSearchValidityTable.idl b/comm/mailnews/search/public/nsIMsgSearchValidityTable.idl new file mode 100644 index 0000000000..75fd4efd51 --- /dev/null +++ b/comm/mailnews/search/public/nsIMsgSearchValidityTable.idl @@ -0,0 +1,32 @@ +/* -*- 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" + +[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); + + readonly attribute long numAvailAttribs; + + Array getAvailableAttributes(); + Array getAvailableOperators(in nsMsgSearchAttribValue attrib); + + void setDefaultAttrib(in nsMsgSearchAttribValue defaultAttrib); +}; diff --git a/comm/mailnews/search/public/nsIMsgSearchValue.idl b/comm/mailnews/search/public/nsIMsgSearchValue.idl new file mode 100644 index 0000000000..6a4cec0b28 --- /dev/null +++ b/comm/mailnews/search/public/nsIMsgSearchValue.idl @@ -0,0 +1,35 @@ +/* -*- 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 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/comm/mailnews/search/public/nsIMsgTraitService.idl b/comm/mailnews/search/public/nsIMsgTraitService.idl new file mode 100644 index 0000000000..23ade21d8d --- /dev/null +++ b/comm/mailnews/search/public/nsIMsgTraitService.idl @@ -0,0 +1,182 @@ +/* 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 identifier "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 "pro" traits to be analyzed by the bayesian code. This is + * a "pro" trait of messages that match the trait. + * Only enabled traits are returned. + * This should return the same number of indices as the corresponding call to + * getEnabledAntiIndices(). + * + * @return an array of trait internal indices for "pro" trait to analyze + */ + Array getEnabledProIndices(); + + /** + * Get an array of "anti" traits to be analyzed by the bayesian code. This is + * a "anti" trait of messages that do not match the trait. + * Only enabled traits are returned. + * This should return the same number of indices as the corresponding call to + * getEnabledProIndices(). + * + * @return an array of trait internal indices for "anti" trait to analyze + */ + Array getEnabledAntiIndices(); + + /** + * 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 + * + * @return an array of internal identifiers for aliases + */ + Array getAliases(in unsigned long aTraitIndex); + +}; diff --git a/comm/mailnews/search/public/nsMsgBodyHandler.h b/comm/mailnews/search/public/nsMsgBodyHandler.h new file mode 100644 index 0000000000..1252e2c20b --- /dev/null +++ b/comm/mailnews/search/public/nsMsgBodyHandler.h @@ -0,0 +1,110 @@ +/* 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); + bool IsQP() { return m_partIsQP; } + + // Transformations + 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 m_fileLineStream; + nsCOMPtr 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 m_msgHdr; + nsCOMPtr 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_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_partIsQP; // true if the Content-Transfer-Encoding header claims + // quoted-printable + 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 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/comm/mailnews/search/public/nsMsgFilterCore.idl b/comm/mailnews/search/public/nsMsgFilterCore.idl new file mode 100644 index 0000000000..42adc5e730 --- /dev/null +++ b/comm/mailnews/search/public/nsMsgFilterCore.idl @@ -0,0 +1,62 @@ +/* -*- 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 : nsISupports { + /* 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 Periodic = 0x100;// On a repeating timer + const long All = Incoming | Manual; +}; + +typedef long nsMsgFilterMotionValue; + +typedef long nsMsgFilterIndex; + +typedef long nsMsgRuleActionType; + +[scriptable, uuid(7726FE79-AFA3-4a39-8292-733AEE288737)] +interface nsMsgFilterAction : nsISupports { + + // 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 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/comm/mailnews/search/public/nsMsgResultElement.h b/comm/mailnews/search/public/nsMsgResultElement.h new file mode 100644 index 0000000000..104e6a3771 --- /dev/null +++ b/comm/mailnews/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: + explicit 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 > m_valueList; + nsIMsgSearchAdapter* m_adapter; + + protected: +}; + +#endif diff --git a/comm/mailnews/search/public/nsMsgSearchAdapter.h b/comm/mailnews/search/public/nsMsgSearchAdapter.h new file mode 100644 index 0000000000..fbfa5176e6 --- /dev/null +++ b/comm/mailnews/search/public/nsMsgSearchAdapter.h @@ -0,0 +1,242 @@ +/* -*- 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 "nsString.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*, + nsTArray> const&); + + NS_DECL_ISUPPORTS + NS_DECL_NSIMSGSEARCHADAPTER + + nsIMsgSearchScopeTerm* m_scope; + nsTArray> + m_searchTerms; /* linked list of criteria terms */ + + nsString m_defaultCharset = u"UTF-8"_ns; + + static nsresult EncodeImap( + char** ppEncoding, nsTArray> const& 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 negotiation 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 m_offlineMailTable; + nsCOMPtr m_offlineMailFilterTable; + nsCOMPtr m_onlineMailTable; + nsCOMPtr m_onlineMailFilterTable; + nsCOMPtr m_onlineManualFilterTable; + + nsCOMPtr m_newsTable; // online news + + // Local news tables, used for local news searching or offline. + nsCOMPtr m_localNewsTable; // base table + nsCOMPtr m_localNewsJunkTable; // base + junk + nsCOMPtr m_localNewsBodyTable; // base + body + nsCOMPtr + m_localNewsJunkBodyTable; // base + junk + body + nsCOMPtr m_ldapTable; + nsCOMPtr m_ldapAndTable; + nsCOMPtr m_localABTable; + nsCOMPtr m_localABAndTable; + nsCOMPtr 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/comm/mailnews/search/public/nsMsgSearchBoolExpression.h b/comm/mailnews/search/public/nsMsgSearchBoolExpression.h new file mode 100644 index 0000000000..1eefd81fcc --- /dev/null +++ b/comm/mailnews/search/public/nsMsgSearchBoolExpression.h @@ -0,0 +1,110 @@ +/* -*- 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 + explicit 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 nsACString& headers, 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/comm/mailnews/search/public/nsMsgSearchCore.idl b/comm/mailnews/search/public/nsMsgSearchCore.idl new file mode 100644 index 0000000000..77b18dfa57 --- /dev/null +++ b/comm/mailnews/search/public/nsMsgSearchCore.idl @@ -0,0 +1,206 @@ +/* -*- 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 : nsISupports { + 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 : nsISupports { + 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 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 : nsISupports { + 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 : nsISupports { + 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 nsMsgSearchBooleanOperator; + +[scriptable, uuid(a37f3f4a-304e-11d3-8f94-00a0c900d445)] +interface nsMsgSearchBooleanOp : nsISupports { + const nsMsgSearchBooleanOperator BooleanOR = 0; + const nsMsgSearchBooleanOperator BooleanAND = 1; +}; + +/* Use this to specify the value of a search term */ + +[ptr] native nsMsgSearchValue(nsMsgSearchValue); + +%{C++ +#include "nsString.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; + uint32_t junkStatus; + uint32_t junkPercent; + } u; + // We keep two versions of the string to avoid conversion at "search time". + nsCString utf8String; + 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::JunkStatus || \ + _a == nsMsgSearchAttrib::FolderFlag || _a == nsMsgSearchAttrib::Uint32HdrProperty || \ + _a == nsMsgSearchAttrib::JunkPercent || _a == nsMsgSearchAttrib::HasAttachmentStatus)) +%} + +[ptr] native nsSearchMenuItem(nsSearchMenuItem); diff --git a/comm/mailnews/search/public/nsMsgSearchScopeTerm.h b/comm/mailnews/search/public/nsMsgSearchScopeTerm.h new file mode 100644 index 0000000000..b76cc676dc --- /dev/null +++ b/comm/mailnews/search/public/nsMsgSearchScopeTerm.h @@ -0,0 +1,44 @@ +/* -*- 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 "nsIWeakReferenceUtils.h" + +class nsMsgSearchScopeTerm : public nsIMsgSearchScopeTerm { + public: + nsMsgSearchScopeTerm(nsIMsgSearchSession*, nsMsgSearchScopeValue, + nsIMsgFolder*); + nsMsgSearchScopeTerm(); + + NS_DECL_ISUPPORTS + NS_DECL_NSIMSGSEARCHSCOPETERM + + nsresult TimeSlice(bool* aDone); + nsresult InitializeAdapter( + nsTArray> const& termList); + + char* GetStatusBarName(); + + nsMsgSearchScopeValue m_attribute; + nsCOMPtr m_folder; + nsCOMPtr m_adapter; + nsCOMPtr m_inputStream; // for message bodies + nsWeakPtr m_searchSession; + bool m_searchServer; + + private: + virtual ~nsMsgSearchScopeTerm(); +}; + +#endif diff --git a/comm/mailnews/search/public/nsMsgSearchTerm.h b/comm/mailnews/search/public/nsMsgSearchTerm.h new file mode 100644 index 0000000000..2ab5618cad --- /dev/null +++ b/comm/mailnews/search/public/nsMsgSearchTerm.h @@ -0,0 +1,89 @@ +/* -*- 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 mDirectory; + + bool mBeginsGrouping; + bool mEndsGrouping; +}; + +#endif -- cgit v1.2.3