From c5e4184a9fa68321fcaa21ce7ba99d3ac2433bc4 Mon Sep 17 00:00:00 2001 From: "alecf%netscape.com" Date: Mon, 1 May 2000 08:15:46 +0000 Subject: [PATCH] expose the message filter's parent list through a scriptable interface, and move more private enums into a public interface --- mailnews/base/search/public/nsIMsgFilter.idl | 3 + .../base/search/public/nsIMsgFilterList.idl | 38 +++++++-- mailnews/base/search/src/nsMsgFilter.cpp | 53 ++++++++---- mailnews/base/search/src/nsMsgFilter.h | 7 +- mailnews/base/search/src/nsMsgFilterList.cpp | 84 +++++++++++-------- mailnews/base/search/src/nsMsgFilterList.h | 24 +----- .../base/search/src/nsMsgFilterService.cpp | 4 +- 7 files changed, 124 insertions(+), 89 deletions(-) diff --git a/mailnews/base/search/public/nsIMsgFilter.idl b/mailnews/base/search/public/nsIMsgFilter.idl index 1364432183d3..7ef63834a8f0 100644 --- a/mailnews/base/search/public/nsIMsgFilter.idl +++ b/mailnews/base/search/public/nsIMsgFilter.idl @@ -34,6 +34,9 @@ interface nsIMsgFilter : nsISupports { attribute boolean enabled; attribute string filterName; attribute string filterDesc; + + readonly attribute nsIMsgFilterList filterList; // owning filter list + void AddTerm(in nsMsgSearchAttribValue attrib, in nsMsgSearchOpValue op, in nsIMsgSearchValue value, diff --git a/mailnews/base/search/public/nsIMsgFilterList.idl b/mailnews/base/search/public/nsIMsgFilterList.idl index 80138ce6ad09..b66862414210 100644 --- a/mailnews/base/search/public/nsIMsgFilterList.idl +++ b/mailnews/base/search/public/nsIMsgFilterList.idl @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * The contents of this file are subject to the Netscape Public * License Version 1.1 (the "License"); you may not use this file @@ -34,10 +34,26 @@ interface nsIOFileStream; // /////////////////////////////////////////////////////////////////////////////// +typedef long nsMsgFilterFileAttribValue; + [scriptable, uuid(08ecbcb4-0493-11d3-a50a-0060b0fc04b7)] 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; + attribute nsIMsgFolder folder; + readonly attribute short version; + readonly attribute unsigned long filterCount; nsIMsgFilter GetFilterAt(in unsigned long filterIndex); /* these methods don't delete filters - they just change the list. @@ -45,26 +61,30 @@ interface nsIMsgFilterList : nsISupports { * call MSG_DestroyFilter to delete a filter. */ - void SetFilterAt(in unsigned long filterIndex, in nsIMsgFilter filter); - void RemoveFilterAt(in unsigned long filterIndex); - void MoveFilterAt(in unsigned long filterIndex, + void setFilterAt(in unsigned long filterIndex, in nsIMsgFilter filter); + void removeFilterAt(in unsigned long filterIndex); + void moveFilterAt(in unsigned long filterIndex, in nsMsgFilterMotionValue motion); - void InsertFilterAt(in unsigned long filterIndex, in nsIMsgFilter filter); + void insertFilterAt(in unsigned long filterIndex, in nsIMsgFilter filter); attribute boolean loggingEnabled; - nsIMsgFilter CreateFilter(in string name); + nsIMsgFilter createFilter(in string name); - void SaveToFile(in nsIOFileStream stream); + void saveToFile(in nsIOFileStream stream); - void ApplyFiltersToHdr(in nsMsgFilterTypeType filterType, + void applyFiltersToHdr(in nsMsgFilterTypeType filterType, in nsIMsgDBHdr msgHdr, in nsIMsgFolder folder, in nsIMsgDatabase db, in string headers, in unsigned long headersSize, in nsIMsgFilterHitNotify listener); - + + // IO routines, used by filter object filing code. + void writeIntAttr(in nsMsgFilterFileAttribValue attrib, in long value); + void writeStrAttr(in nsMsgFilterFileAttribValue attrib, in string value); + void writeBoolAttr(in nsMsgFilterFileAttribValue attrib, in boolean value); }; diff --git a/mailnews/base/search/src/nsMsgFilter.cpp b/mailnews/base/search/src/nsMsgFilter.cpp index 2f26fad560d3..f38515d73e0a 100644 --- a/mailnews/base/search/src/nsMsgFilter.cpp +++ b/mailnews/base/search/src/nsMsgFilter.cpp @@ -21,12 +21,12 @@ * Pierre Phaneuf */ -// this file implements the nsMsgFilterList interface +// this file implements the nsMsgFilter interface #include "msgCore.h" #include "nsMsgBaseCID.h" #include "nsIMsgHdr.h" -#include "nsMsgFilterList.h" +#include "nsMsgFilterList.h" // for kFileVersion #include "nsMsgFilter.h" #include "nsMsgUtils.h" #include "nsFileStream.h" @@ -48,9 +48,9 @@ nsMsgRuleAction::~nsMsgRuleAction() } -nsMsgFilter::nsMsgFilter() +nsMsgFilter::nsMsgFilter() : + m_filterList(nsnull) { - m_filterList = nsnull; NS_INIT_REFCNT(); } @@ -307,11 +307,22 @@ NS_IMETHODIMP nsMsgFilter::MatchHdr(nsIMsgDBHdr *msgHdr, nsIMsgFolder *folder, n pResult); } -void nsMsgFilter::SetFilterList(nsMsgFilterList *filterList) +void +nsMsgFilter::SetFilterList(nsIMsgFilterList *filterList) { + // hold weak ref m_filterList = filterList; } +nsresult +nsMsgFilter::GetFilterList(nsIMsgFilterList **aResult) +{ + NS_ENSURE_ARG_POINTER(aResult); + *aResult = m_filterList; + NS_IF_ADDREF(*aResult); + return NS_OK; +} + void nsMsgFilter::SetFilterScript(nsCString *fileName) { m_scriptFileName = *fileName; @@ -322,7 +333,7 @@ nsresult nsMsgFilter::ConvertMoveToFolderValue(nsCString &moveValue) PRInt16 filterVersion = kFileVersion; if (m_filterList) - filterVersion = m_filterList->GetVersion(); + m_filterList->GetVersion(&filterVersion); if (filterVersion <= k60Beta1Version) { nsCOMPtr rootFolder; @@ -401,12 +412,12 @@ nsresult nsMsgFilter::ConvertMoveToFolderValue(nsCString &moveValue) nsresult nsMsgFilter::SaveToTextFile(nsIOFileStream *stream) { - nsresult err = m_filterList->WriteStrAttr(nsMsgFilterAttribName, m_filterName); - err = m_filterList->WriteBoolAttr(nsMsgFilterAttribEnabled, m_enabled); - err = m_filterList->WriteStrAttr(nsMsgFilterAttribDescription, m_description); - err = m_filterList->WriteIntAttr(nsMsgFilterAttribType, m_type); + nsresult err = m_filterList->WriteStrAttr(nsIMsgFilterList::attribName, m_filterName); + err = m_filterList->WriteBoolAttr(nsIMsgFilterList::attribEnabled, m_enabled); + err = m_filterList->WriteStrAttr(nsIMsgFilterList::attribDescription, m_description); + err = m_filterList->WriteIntAttr(nsIMsgFilterList::attribType, m_type); if (IsScript()) - err = m_filterList->WriteStrAttr(nsMsgFilterAttribScriptFile, m_scriptFileName); + err = m_filterList->WriteStrAttr(nsIMsgFilterList::attribScriptFile, m_scriptFileName); else err = SaveRule(); return err; @@ -416,12 +427,13 @@ nsresult nsMsgFilter::SaveRule() { nsresult err = NS_OK; //char *relativePath = nsnull; - nsMsgFilterList *filterList = GetFilterList(); + nsIMsgFilterList *filterList; + GetFilterList(&filterList); nsCAutoString actionFilingStr; GetActionFilingStr(m_action.m_type, actionFilingStr); - err = filterList->WriteStrAttr(nsMsgFilterAttribAction, actionFilingStr); + err = filterList->WriteStrAttr(nsIMsgFilterList::attribAction, actionFilingStr); if (!NS_SUCCEEDED(err)) return err; switch(m_action.m_type) @@ -429,7 +441,7 @@ nsresult nsMsgFilter::SaveRule() case nsMsgFilterAction::MoveToFolder: { nsCAutoString imapTargetString(m_action.m_folderUri); - err = filterList->WriteStrAttr(nsMsgFilterAttribActionValue, imapTargetString); + err = filterList->WriteStrAttr(nsIMsgFilterList::attribActionValue, imapTargetString); } break; case nsMsgFilterAction::ChangePriority: @@ -438,7 +450,7 @@ nsresult nsMsgFilter::SaveRule() NS_MsgGetUntranslatedPriorityName (m_action.m_priority, &priority); nsCAutoString cStr; cStr.AssignWithConversion(priority); - err = filterList->WriteStrAttr(nsMsgFilterAttribActionValue, cStr); + err = filterList->WriteStrAttr(nsIMsgFilterList::attribActionValue, cStr); } break; default: @@ -475,7 +487,7 @@ nsresult nsMsgFilter::SaveRule() condition += ')'; } if (NS_SUCCEEDED(err)) - err = filterList->WriteStrAttr(nsMsgFilterAttribCondition, condition); + err = filterList->WriteStrAttr(nsIMsgFilterList::attribCondition, condition); return err; } @@ -540,6 +552,15 @@ nsMsgRuleActionType nsMsgFilter::GetActionForFilingStr(nsCString &actionStr) return nsMsgFilterAction::None; } +PRInt16 +nsMsgFilter::GetVersion() +{ + if (!m_filterList) return 0; + PRInt16 version; + m_filterList->GetVersion(&version); + return version; +} + #ifdef DEBUG void nsMsgFilter::Dump() { diff --git a/mailnews/base/search/src/nsMsgFilter.h b/mailnews/base/search/src/nsMsgFilter.h index 74948f3ee3c9..8ad7e9956e21 100644 --- a/mailnews/base/search/src/nsMsgFilter.h +++ b/mailnews/base/search/src/nsMsgFilter.h @@ -57,7 +57,7 @@ public: void SetType(nsMsgFilterTypeType type) {m_type = type;} PRBool GetEnabled() {return m_enabled;} void SetFilterScript(nsCString *filterName) ; - void SetFilterList(nsMsgFilterList *filterList) ; + void SetFilterList(nsIMsgFilterList* filterList); PRBool IsRule() {return (m_type & (nsMsgFilterType::InboxRule | nsMsgFilterType::NewsRule)) != 0;} @@ -69,8 +69,7 @@ public: nsresult SaveToTextFile(nsIOFileStream *stream); nsresult SaveRule(); - PRInt16 GetVersion() {return (m_filterList) ? m_filterList->GetVersion() : 0;} - nsMsgFilterList *GetFilterList() {return m_filterList;} + PRInt16 GetVersion(); void SetDontFileMe(PRBool bDontFileMe) {m_dontFileMe = bDontFileMe;} nsMsgSearchTermArray* GetTermList() {return &m_termList;} /* linked list of criteria terms */ #ifdef DEBUG @@ -90,7 +89,7 @@ protected: nsCString m_description; PRBool m_dontFileMe; - nsMsgFilterList *m_filterList; /* owning filter list */ + nsIMsgFilterList *m_filterList; /* owning filter list */ nsMsgSearchTermArray m_termList; /* linked list of criteria terms */ nsCOMPtr m_scope; /* default for mail rules is inbox, but news rules could have a newsgroup - LDAP would be invalid */ diff --git a/mailnews/base/search/src/nsMsgFilterList.cpp b/mailnews/base/search/src/nsMsgFilterList.cpp index 0f2e422356c3..c2f03a31509f 100644 --- a/mailnews/base/search/src/nsMsgFilterList.cpp +++ b/mailnews/base/search/src/nsMsgFilterList.cpp @@ -260,23 +260,23 @@ extern "C" MSG_FolderInfo *MSG_GetFolderInfoForFilterList(nsMsgFilterList *filte typedef struct { - nsMsgFilterFileAttrib attrib; + nsMsgFilterFileAttribValue attrib; const char *attribName; } FilterFileAttribEntry; static FilterFileAttribEntry FilterFileAttribTable[] = { - {nsMsgFilterAttribNone, ""}, - {nsMsgFilterAttribVersion, "version"}, - {nsMsgFilterAttribLogging, "logging"}, - {nsMsgFilterAttribName, "name"}, - {nsMsgFilterAttribEnabled, "enabled"}, - {nsMsgFilterAttribDescription, "description"}, - {nsMsgFilterAttribType, "type"}, - {nsMsgFilterAttribScriptFile, "scriptName"}, - {nsMsgFilterAttribAction, "action"}, - {nsMsgFilterAttribActionValue, "actionValue"}, - {nsMsgFilterAttribCondition, "condition"} + {nsIMsgFilterList::attribNone, ""}, + {nsIMsgFilterList::attribVersion, "version"}, + {nsIMsgFilterList::attribLogging, "logging"}, + {nsIMsgFilterList::attribName, "name"}, + {nsIMsgFilterList::attribEnabled, "enabled"}, + {nsIMsgFilterList::attribDescription, "description"}, + {nsIMsgFilterList::attribType, "type"}, + {nsIMsgFilterList::attribScriptFile, "scriptName"}, + {nsIMsgFilterList::attribAction, "action"}, + {nsIMsgFilterList::attribActionValue, "actionValue"}, + {nsIMsgFilterList::attribCondition, "condition"} }; // If we want to buffer file IO, wrap it in here. @@ -307,7 +307,7 @@ PRBool nsMsgFilterList::StrToBool(nsCString &str) return str.Equals("yes") ; } -char nsMsgFilterList::LoadAttrib(nsMsgFilterFileAttrib &attrib) +char nsMsgFilterList::LoadAttrib(nsMsgFilterFileAttribValue &attrib) { char attribStr[100]; char curChar; @@ -333,7 +333,7 @@ char nsMsgFilterList::LoadAttrib(nsMsgFilterFileAttrib &attrib) return curChar; } -const char *nsMsgFilterList::GetStringForAttrib(nsMsgFilterFileAttrib attrib) +const char *nsMsgFilterList::GetStringForAttrib(nsMsgFilterFileAttribValue attrib) { for (int tableIndex = 0; tableIndex < (int)(sizeof(FilterFileAttribTable) / sizeof(FilterFileAttribTable[0])); tableIndex++) { @@ -390,7 +390,7 @@ nsresult nsMsgFilterList::LoadValue(nsCString &value) nsresult nsMsgFilterList::LoadTextFilters() { nsresult err = NS_OK; - nsMsgFilterFileAttrib attrib; + nsMsgFilterFileAttribValue attrib; // We'd really like to move lot's of these into the objects that they refer to. m_fileStream->seek(PR_SEEK_SET, 0); @@ -402,27 +402,27 @@ nsresult nsMsgFilterList::LoadTextFilters() char curChar; curChar = LoadAttrib(attrib); - if (attrib == nsMsgFilterAttribNone) + if (attrib == nsIMsgFilterList::attribNone) break; err = LoadValue(value); if (err != NS_OK) break; switch(attrib) { - case nsMsgFilterAttribNone: + case nsIMsgFilterList::attribNone: break; - case nsMsgFilterAttribVersion: + case nsIMsgFilterList::attribVersion: m_fileVersion = value.ToInteger(&intToStringResult, 10); if (intToStringResult != 0) { - attrib = nsMsgFilterAttribNone; + attrib = nsIMsgFilterList::attribNone; NS_ASSERTION(PR_FALSE, "error parsing filter file version"); } break; - case nsMsgFilterAttribLogging: + case nsIMsgFilterList::attribLogging: m_loggingEnabled = StrToBool(value); break; - case nsMsgFilterAttribName: + case nsIMsgFilterList::attribName: { nsMsgFilter *filter = new nsMsgFilter; if (filter == nsnull) @@ -430,34 +430,34 @@ nsresult nsMsgFilterList::LoadTextFilters() err = NS_ERROR_OUT_OF_MEMORY; break; } - filter->SetFilterList(this); + filter->SetFilterList(NS_STATIC_CAST(nsIMsgFilterList*,this)); filter->SetFilterName(value.GetBuffer()); m_curFilter = filter; m_filters->AppendElement(filter); } break; - case nsMsgFilterAttribEnabled: + case nsIMsgFilterList::attribEnabled: if (m_curFilter) m_curFilter->SetEnabled(StrToBool(value)); break; - case nsMsgFilterAttribDescription: + case nsIMsgFilterList::attribDescription: if (m_curFilter) m_curFilter->SetFilterDesc(value.GetBuffer()); break; - case nsMsgFilterAttribType: + case nsIMsgFilterList::attribType: if (m_curFilter) { m_curFilter->SetType((nsMsgFilterTypeType) value.ToInteger(&intToStringResult, 10)); } break; - case nsMsgFilterAttribScriptFile: + case nsIMsgFilterList::attribScriptFile: if (m_curFilter) m_curFilter->SetFilterScript(&value); break; - case nsMsgFilterAttribAction: + case nsIMsgFilterList::attribAction: m_curFilter->m_action.m_type = nsMsgFilter::GetActionForFilingStr(value); break; - case nsMsgFilterAttribActionValue: + case nsIMsgFilterList::attribActionValue: if (m_curFilter->m_action.m_type == nsMsgFilterAction::MoveToFolder) err = m_curFilter->ConvertMoveToFolderValue(value); else if (m_curFilter->m_action.m_type == nsMsgFilterAction::ChangePriority) @@ -473,11 +473,11 @@ nsresult nsMsgFilterList::LoadTextFilters() } break; - case nsMsgFilterAttribCondition: + case nsIMsgFilterList::attribCondition: err = ParseCondition(value); break; } - } while (attrib != nsMsgFilterAttribNone); + } while (attrib != nsIMsgFilterList::attribNone); return err; } @@ -558,7 +558,7 @@ nsresult nsMsgFilterList::ParseCondition(nsCString &value) return err; } -nsresult nsMsgFilterList::WriteIntAttr(nsMsgFilterFileAttrib attrib, int value) +nsresult nsMsgFilterList::WriteIntAttr(nsMsgFilterFileAttribValue attrib, int value) { const char *attribStr = GetStringForAttrib(attrib); if (attribStr) @@ -572,9 +572,11 @@ nsresult nsMsgFilterList::WriteIntAttr(nsMsgFilterFileAttrib attrib, int value) return NS_OK; } -nsresult nsMsgFilterList::WriteStrAttr(nsMsgFilterFileAttrib attrib, nsCString &str) +nsresult +nsMsgFilterList::WriteStrAttr(nsMsgFilterFileAttribValue attrib, + const char *str) { - if (!str.IsEmpty() && m_fileStream) // only proceed if we actually have a string to write out. + if (str && str[0] && m_fileStream) // only proceed if we actually have a string to write out. { char *escapedStr = nsnull; if (PL_strchr(str, '"')) @@ -594,7 +596,7 @@ nsresult nsMsgFilterList::WriteStrAttr(nsMsgFilterFileAttrib attrib, nsCString & return NS_OK; } -nsresult nsMsgFilterList::WriteBoolAttr(nsMsgFilterFileAttrib attrib, PRBool boolVal) +nsresult nsMsgFilterList::WriteBoolAttr(nsMsgFilterFileAttribValue attrib, PRBool boolVal) { nsCString strToWrite((boolVal) ? "yes" : "no"); return WriteStrAttr(attrib, strToWrite); @@ -607,9 +609,9 @@ nsresult nsMsgFilterList::SaveTextFilters() PRUint32 filterCount; m_filters->Count(&filterCount); - attribStr = GetStringForAttrib(nsMsgFilterAttribVersion); - err = WriteIntAttr(nsMsgFilterAttribVersion, kFileVersion); - err = WriteBoolAttr(nsMsgFilterAttribLogging, m_loggingEnabled); + attribStr = GetStringForAttrib(nsIMsgFilterList::attribVersion); + err = WriteIntAttr(nsIMsgFilterList::attribVersion, kFileVersion); + err = WriteBoolAttr(nsIMsgFilterList::attribLogging, m_loggingEnabled); for (PRUint32 i = 0; i < filterCount; i ++) { nsMsgFilter *filter; @@ -765,6 +767,14 @@ nsresult nsMsgFilterList::MoveFilterAt(PRUint32 filterIndex, return NS_OK; } +nsresult +nsMsgFilterList::GetVersion(PRInt16 *aResult) +{ + NS_ENSURE_ARG_POINTER(aResult); + *aResult = m_fileVersion; + return NS_OK; +} + #ifdef DEBUG void nsMsgFilterList::Dump() diff --git a/mailnews/base/search/src/nsMsgFilterList.h b/mailnews/base/search/src/nsMsgFilterList.h index 50c1cac549c0..62938bb9df4f 100644 --- a/mailnews/base/search/src/nsMsgFilterList.h +++ b/mailnews/base/search/src/nsMsgFilterList.h @@ -45,20 +45,6 @@ class nsIMsgFilter; class nsIOFileStream; class nsMsgFilter; -typedef enum -{ - nsMsgFilterAttribNone, - nsMsgFilterAttribVersion, - nsMsgFilterAttribLogging, - nsMsgFilterAttribName, - nsMsgFilterAttribEnabled, - nsMsgFilterAttribDescription, - nsMsgFilterAttribType, - nsMsgFilterAttribScriptFile, - nsMsgFilterAttribAction, - nsMsgFilterAttribActionValue, - nsMsgFilterAttribCondition -} nsMsgFilterFileAttrib; class nsMsgFilterList : public nsIMsgFilterList { @@ -74,12 +60,6 @@ public: nsresult Close(); nsresult LoadTextFilters(); - PRInt16 GetVersion() {return m_fileVersion;} - - // IO routines, used by filter object filing code. - nsresult WriteIntAttr( nsMsgFilterFileAttrib attrib, int value); - nsresult WriteStrAttr(nsMsgFilterFileAttrib attrib, nsCString &str); - nsresult WriteBoolAttr(nsMsgFilterFileAttrib attrib, PRBool boolVal); protected: // type-safe accessor when you really have to have an nsMsgFilter nsresult GetMsgFilterAt(PRUint32 filterIndex, nsMsgFilter **filter); @@ -93,8 +73,8 @@ protected: PRBool IsWhitespace(char ch); char SkipWhitespace(); PRBool StrToBool(nsCString &str); - char LoadAttrib(nsMsgFilterFileAttrib &attrib); - const char *GetStringForAttrib(nsMsgFilterFileAttrib attrib); + char LoadAttrib(nsMsgFilterFileAttribValue &attrib); + const char *GetStringForAttrib(nsMsgFilterFileAttribValue attrib); nsresult LoadValue(nsCString &value); nsresult ParseCondition(nsCString &value); PRInt16 m_fileVersion; diff --git a/mailnews/base/search/src/nsMsgFilterService.cpp b/mailnews/base/search/src/nsMsgFilterService.cpp index 4a99ea396163..00bff7d80afb 100644 --- a/mailnews/base/search/src/nsMsgFilterService.cpp +++ b/mailnews/base/search/src/nsMsgFilterService.cpp @@ -79,7 +79,9 @@ NS_IMETHODIMP nsMsgFilterService::OpenFilterList(nsFileSpec *filterFile, nsIMsgF if (NS_SUCCEEDED(ret)) { *resultFilterList = filterList; - if (filterList->GetVersion() != kFileVersion) + PRInt16 version; + filterList->GetVersion(&version); + if (version != kFileVersion) { SaveFilterList(filterList, filterFile);