зеркало из https://github.com/mozilla/pjs.git
Added folder listener so we can run the mailbox parsing url.
This commit is contained in:
Родитель
adc2d06dd4
Коммит
a6de9c9ef0
|
@ -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;
|
||||
|
||||
#ifdef DEBUG
|
||||
mMailDatabase->PrePopulate();
|
||||
#endif
|
||||
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;
|
||||
}
|
||||
|
||||
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))
|
||||
{
|
||||
|
@ -345,10 +356,36 @@ NS_IMETHODIMP nsMSGFolderDataSource::GetTarget(nsIRDFResource* source,
|
|||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче