Added folder listener so we can run the mailbox parsing url.

This commit is contained in:
putterman%netscape.com 1999-03-09 22:37:55 +00:00
Родитель adc2d06dd4
Коммит a6de9c9ef0
4 изменённых файлов: 232 добавлений и 23 удалений

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

@ -28,15 +28,22 @@
#include "nsIServiceManager.h"
#include "nsIEnumerator.h"
#include "nsMailDatabase.h"
#include "nsIMailboxService.h"
#include "nsParseMailbox.h"
#include "nsIFolderListener.h"
#include "nsCOMPtr.h"
#include "nsIRDFService.h"
#include "nsIRDFDataSource.h"
#include "nsRDFCID.h"
// we need this because of an egcs 1.0 (and possibly gcc) compiler bug
// that doesn't allow you to call ::nsISupports::GetIID() inside of a class
// that multiply inherits from nsISupports
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
static NS_DEFINE_CID(kMailboxServiceCID, NS_MAILBOXSERVICE_CID);
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
@ -132,6 +139,25 @@ nsMsgLocalMailFolder::CreateSubFolders(void)
return rv;
}
//run the url to parse the mailbox
nsresult nsMsgLocalMailFolder::ParseFolder(nsFileSpec& path)
{
nsresult rv = NS_OK;
nsIMailboxService *mailboxService;
rv = nsServiceManager::GetService(kMailboxServiceCID, nsIMailboxService::GetIID(),
(nsISupports**)&mailboxService);
if (NS_FAILED(rv)) return rv;
nsMsgMailboxParser *parser = new nsMsgMailboxParser;
if(!parser)
return NS_ERROR_OUT_OF_MEMORY;
rv = mailboxService->ParseMailbox(path, parser, nsnull, nsnull);
nsServiceManager::ReleaseService(kMailboxServiceCID, mailboxService);
return rv;
}
NS_IMETHODIMP
nsMsgLocalMailFolder::Enumerate(nsIEnumerator* *result)
{
@ -221,23 +247,38 @@ nsMsgLocalMailFolder::ReplaceElement(nsISupports* element, nsISupports* newEleme
NS_IMETHODIMP
nsMsgLocalMailFolder::GetMessages(nsIEnumerator* *result)
{
if (mMailDatabase == nsnull) {
if (mMailDatabase == nsnull)
{
nsNativeFileSpec path;
nsresult rv = GetPath(path);
if (NS_FAILED(rv)) return rv;
PRBool upgrading = PR_FALSE;
#ifdef DEBUG_warren
upgrading = PR_TRUE;
#endif
rv = nsMailDatabase::Open(path, PR_TRUE, &mMailDatabase, upgrading);
if (NS_FAILED(rv)) return rv;
nsresult folderOpen;
if(!NS_SUCCEEDED(folderOpen = nsMailDatabase::Open(path, PR_TRUE, &mMailDatabase, PR_FALSE)) &&
folderOpen == NS_MSG_ERROR_FOLDER_SUMMARY_OUT_OF_DATE)
{
// if it's out of date then reopen with upgrade.
if(!NS_SUCCEEDED(rv = nsMailDatabase::Open(path, PR_TRUE, &mMailDatabase, PR_TRUE)))
return rv;
}
#ifdef DEBUG
mMailDatabase->PrePopulate();
#endif
if(mMailDatabase)
{
mMailDatabase->AddListener(this);
// if we have to regenerate the folder, run the parser url.
if(folderOpen == NS_MSG_ERROR_FOLDER_SUMMARY_MISSING || folderOpen == NS_MSG_ERROR_FOLDER_SUMMARY_OUT_OF_DATE)
{
if(NS_FAILED(rv = ParseFolder(path)))
return rv;
}
}
}
return mMailDatabase->EnumerateMessages(result);
}
NS_IMETHODIMP nsMsgLocalMailFolder::BuildFolderURL(char **url)
@ -841,3 +882,59 @@ NS_IMETHODIMP nsMsgLocalMailFolder::GetPath(nsFileSpec& aPathName)
aPathName = mPath;
return NS_OK;
}
NS_IMETHODIMP nsMsgLocalMailFolder::OnKeyChange(nsMsgKey aKeyChanged, int32 aFlags,
nsIDBChangeListener * aInstigator)
{
return NS_OK;
}
NS_IMETHODIMP nsMsgLocalMailFolder::OnKeyDeleted(nsMsgKey aKeyChanged, int32 aFlags,
nsIDBChangeListener * aInstigator)
{
return NS_OK;
}
NS_IMETHODIMP nsMsgLocalMailFolder::OnKeyAdded(nsMsgKey aKeyChanged, int32 aFlags,
nsIDBChangeListener * aInstigator)
{
nsIMessage *pMessage;
mMailDatabase->GetMsgHdrForKey(aKeyChanged, &pMessage);
nsString author, subject;
nsISupports *msgSupports;
if(NS_SUCCEEDED(pMessage->QueryInterface(kISupportsIID, (void**)&msgSupports)))
{
//XXXX This is a hack for the moment. I'm assuming the only listener is our rdf:mailnews datasource.
//In reality anyone should be able to listen to folder changes.
nsIRDFService* rdfService = nsnull;
nsIRDFDataSource* datasource = nsnull;
nsresult rv = nsServiceManager::GetService(kRDFServiceCID,
nsIRDFService::GetIID(),
(nsISupports**) &rdfService);
if(NS_SUCCEEDED(rv))
{
if(NS_SUCCEEDED(rv = rdfService->GetDataSource("rdf:mailnews", &datasource)))
{
nsIFolderListener *folderListener;
if(NS_SUCCEEDED(datasource->QueryInterface(nsIFolderListener::GetIID(), (void**)&folderListener)))
{
folderListener->OnItemAdded(this, msgSupports);
NS_RELEASE(folderListener);
}
NS_RELEASE(datasource);
}
nsServiceManager::ReleaseService(kRDFServiceCID, rdfService);
}
NS_RELEASE(msgSupports);
}
return NS_OK;
}
NS_IMETHODIMP nsMsgLocalMailFolder::OnAnnouncerGoingAway(nsIDBChangeAnnouncer * instigator)
{
return NS_OK;
}

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

@ -28,8 +28,10 @@
#include "nsMsgFolder.h" /* include the interface we are going to support */
#include "nsMailDatabase.h"
#include "nsFileSpec.h"
#include "nsIDBChangeListener.h"
class nsMsgLocalMailFolder : public nsMsgFolder, public nsIMsgLocalMailFolder
class nsMsgLocalMailFolder : public nsMsgFolder, public nsIMsgLocalMailFolder,
public nsIDBChangeListener
{
public:
nsMsgLocalMailFolder(void);
@ -104,7 +106,18 @@ public:
// nsIMsgMailFolder
NS_IMETHOD GetPath(nsNativeFileSpec& aPathName);
//nsIDBChangeListener
NS_IMETHOD OnKeyChange(nsMsgKey aKeyChanged, int32 aFlags,
nsIDBChangeListener * aInstigator);
NS_IMETHOD OnKeyDeleted(nsMsgKey aKeyChanged, int32 aFlags,
nsIDBChangeListener * aInstigator);
NS_IMETHOD OnKeyAdded(nsMsgKey aKeyChanged, int32 aFlags,
nsIDBChangeListener * aInstigator);
NS_IMETHOD OnAnnouncerGoingAway(nsIDBChangeAnnouncer * instigator);
protected:
nsresult ParseFolder(nsFileSpec& path);
nsresult CreateSubFolders(void);
protected:
@ -113,8 +126,8 @@ protected:
PRBool mHaveReadNameFromDB;
PRBool mGettingMail;
PRBool mInitialized;
nsMailDatabase* mMailDatabase;
nsISupportsArray *mMessages;
nsMailDatabase* mMailDatabase;
};
#endif // nsMsgLocalMailFolder_h__

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

@ -39,9 +39,13 @@
#include "nsRDFCursorUtils.h"
#include "nsIMessage.h"
#include "nsMsgFolder.h"
#include "nsIMsgRFC822Parser.h"
#include "nsMsgBaseCID.h"
static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
static NS_DEFINE_CID(kRDFInMemoryDataSourceCID, NS_RDFINMEMORYDATASOURCE_CID);
static NS_DEFINE_CID(kMsgRFC822ParserCID, NS_MSGRFC822PARSER_CID);
// we need this because of an egcs 1.0 (and possibly gcc) compiler bug
// that doesn't allow you to call ::nsISupports::GetIID() inside of a class
@ -194,6 +198,12 @@ nsMSGFolderDataSource::QueryInterface(REFNSIID iid, void** result)
AddRef();
return NS_OK;
}
else if(iid.Equals(nsIFolderListener::GetIID()))
{
*result = NS_STATIC_CAST(nsIFolderListener*, this);
AddRef();
return NS_OK;
}
return NS_NOINTERFACE;
}
@ -272,6 +282,7 @@ NS_IMETHODIMP nsMSGFolderDataSource::GetTarget(nsIRDFResource* source,
if (! tv)
return NS_ERROR_RDF_NO_VALUE;
nsCOMPtr<nsIMsgFolder> folder(do_QueryInterface(source, &rv));
if (NS_SUCCEEDED(rv)) {
if (peq(kNC_Name, property)) {
@ -324,7 +335,6 @@ NS_IMETHODIMP nsMSGFolderDataSource::GetTarget(nsIRDFResource* source,
nsCOMPtr<nsIMessage> message(do_QueryInterface(source, &rv));
if (NS_SUCCEEDED(rv)) {
if (peq(kNC_Name, property) ||
peq(kNC_Subject, property)) {
nsAutoString subject;
@ -333,9 +343,10 @@ NS_IMETHODIMP nsMSGFolderDataSource::GetTarget(nsIRDFResource* source,
}
else if (peq(kNC_Sender, property))
{
nsAutoString sender;
nsAutoString sender, senderUserName;
rv = message->GetProperty("sender", sender);
createNode(sender, target);
if(NS_SUCCEEDED(rv = GetSenderName(sender, &senderUserName)))
createNode(senderUserName, target);
}
else if (peq(kNC_Date, property))
{
@ -349,6 +360,32 @@ NS_IMETHODIMP nsMSGFolderDataSource::GetTarget(nsIRDFResource* source,
return rv;
}
//sender is the string we need to parse. senderuserName is the parsed user name we get back.
nsresult nsMSGFolderDataSource::GetSenderName(nsAutoString& sender, nsAutoString *senderUserName)
{
//XXXOnce we get the csid, use Intl version
nsIMsgRFC822Parser *parser;
nsresult rv = NS_OK;
if(NS_SUCCEEDED(rv = nsComponentManager::CreateInstance(kMsgRFC822ParserCID,
NULL,
nsIMsgRFC822Parser::GetIID(),
(void **) &parser)))
{
char *name;
char *senderStr = sender.ToNewCString();
if(NS_SUCCEEDED(rv = parser->ExtractRFC822AddressName (senderStr, &name)))
{
*senderUserName = name;
}
if(name)
PL_strfree(name);
if(senderStr)
delete[] senderStr;
NS_RELEASE(parser);
}
return rv;
}
NS_IMETHODIMP nsMSGFolderDataSource::GetSources(nsIRDFResource* property,
nsIRDFNode* target,
PRBool tv,
@ -365,6 +402,7 @@ NS_IMETHODIMP nsMSGFolderDataSource::GetTargets(nsIRDFResource* source,
{
nsresult rv = NS_ERROR_FAILURE;
nsIMsgFolder* folder;
nsIMessage* message;
if (NS_SUCCEEDED(source->QueryInterface(nsIMsgFolder::GetIID(), (void**)&folder)))
@ -473,6 +511,33 @@ NS_IMETHODIMP nsMSGFolderDataSource::RemoveObserver(nsIRDFObserver* n)
return NS_OK;
}
nsresult nsMSGFolderDataSource::NotifyObservers(nsIRDFResource *subject, nsIRDFResource *property,
nsIRDFNode *object, PRBool assert)
{
if(mObservers)
{
PRInt32 numObservers = mObservers->Count();
nsIRDFObserver *observer = nsnull;
for(PRInt32 i = 0; i < numObservers; i++)
{
//Get each observer and tell it an assert or unassert happened.
observer = (nsIRDFObserver*)mObservers->ElementAt(i);
if(observer)
{
if(assert)
{
observer->OnAssert(subject, property, object);
}
else
{
observer->OnUnassert(subject, property, object);
}
}
}
}
return NS_OK;
}
NS_IMETHODIMP nsMSGFolderDataSource::ArcLabelsIn(nsIRDFNode* node,
nsIRDFArcsInCursor** labels)
{
@ -487,6 +552,7 @@ NS_IMETHODIMP nsMSGFolderDataSource::ArcLabelsOut(nsIRDFResource* source,
NS_NewISupportsArray(&arcs);
if (arcs == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
nsIMsgFolder* folder;
nsIMessage* message;
if (NS_SUCCEEDED(source->QueryInterface(nsIMsgFolder::GetIID(), (void**)&folder)))
@ -560,10 +626,28 @@ NS_IMETHODIMP nsMSGFolderDataSource::DoCommand(const char* aCommand,
return NS_ERROR_NOT_IMPLEMENTED;
}
/*
NS_IMETHODIMP nsMSGFolderDataSource::OnItemAdded(nsIFolder *parentFolder, nsISupports *item)
{
return NS_ERROR_NOT_IMPLEMENTED;
nsIMessage *message;
nsIRDFResource *parentResource;
if(NS_SUCCEEDED(parentFolder->QueryInterface(nsIRDFResource::GetIID(), (void**)&parentResource)))
{
//If we are adding a message
if(NS_SUCCEEDED(item->QueryInterface(nsIMessage::GetIID(), (void**)&message)))
{
nsIRDFNode *itemNode;
if(NS_SUCCEEDED(item->QueryInterface(nsIRDFNode::GetIID(), (void**)&itemNode)))
{
//Notify folders that a message was added.
NotifyObservers(parentResource, kNC_MessageChild, itemNode, PR_TRUE);
NS_RELEASE(itemNode);
}
NS_RELEASE(message);
}
NS_RELEASE(parentResource);
}
return NS_OK;
}
NS_IMETHODIMP nsMSGFolderDataSource::OnItemRemoved(nsIFolder *parentFolder, nsISupports *item)
@ -576,4 +660,4 @@ NS_IMETHODIMP nsMSGFolderDataSource::OnItemPropertyChanged(nsISupports *item, ch
return NS_ERROR_NOT_IMPLEMENTED;
}
*/

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

@ -23,11 +23,12 @@
#include "nsIRDFNode.h"
#include "nsIRDFCursor.h"
#include "nsFileSpec.h"
#include "nsIFolderListener.h"
/**
* The mail data source.
*/
class nsMSGFolderDataSource : public nsIRDFMSGFolderDataSource
class nsMSGFolderDataSource : public nsIRDFMSGFolderDataSource, public nsIFolderListener
{
private:
char* mURI;
@ -103,7 +104,19 @@ public:
NS_IMETHOD DoCommand(const char* aCommand,
nsIRDFResource* aCommandTarget);
NS_IMETHOD OnItemAdded(nsIFolder *parentFolder, nsISupports *item);
NS_IMETHOD OnItemRemoved(nsIFolder *parentFolder, nsISupports *item);
NS_IMETHOD OnItemPropertyChanged(nsISupports *item, char *property, char *value);
// caching frequently used resources
protected:
nsresult NotifyObservers(nsIRDFResource *subject, nsIRDFResource *property,
nsIRDFNode *object, PRBool assert);
nsresult GetSenderName(nsAutoString& sender, nsAutoString *senderUserName);
static nsIRDFResource* kNC_Child;
static nsIRDFResource* kNC_MessageChild;
static nsIRDFResource* kNC_Folder;
@ -114,5 +127,7 @@ public:
static nsIRDFResource* kNC_Subject;
static nsIRDFResource* kNC_Sender;
static nsIRDFResource* kNC_Date;
};