зеркало из https://github.com/mozilla/pjs.git
add ability to create storage for folders on demand, e.g., templates and drafts, r=mscott 45146
This commit is contained in:
Родитель
f0409f54b0
Коммит
d1cbb2ce9c
|
@ -138,6 +138,12 @@ const nsMsgBiffState nsMsgBiffState_Unknown = 2; // We dunno whether there is ne
|
|||
|
||||
void createSubfolder(in wstring folderName);
|
||||
[noscript] nsIMsgFolder addSubfolder(in nsAutoString folderName);
|
||||
/* this method ensures the storage for the folder exists.
|
||||
For local folders, it creates the berkeley mailbox if missing.
|
||||
For imap folders, it subscribes to the folder if it exists,
|
||||
or creates it if it doesn't exist
|
||||
*/
|
||||
void createStorageIfMissing(in nsIUrlListener urlListener);
|
||||
|
||||
void compact();
|
||||
void emptyTrash(in nsIMsgWindow aMsgWindow, in nsIUrlListener aListener);
|
||||
|
|
|
@ -1038,6 +1038,15 @@ NS_IMETHODIMP nsMsgFolder::DeleteSubFolders(nsISupportsArray *folders,
|
|||
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgFolder::CreateStorageIfMissing(nsIUrlListener* /* urlListener */)
|
||||
{
|
||||
NS_ASSERTION(PR_FALSE, "needs to be overridden");
|
||||
nsresult status = NS_OK;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsMsgFolder::PropagateDelete(nsIMsgFolder *folder, PRBool deleteStorage)
|
||||
{
|
||||
nsresult status = NS_OK;
|
||||
|
|
|
@ -90,6 +90,7 @@ public:
|
|||
NS_IMETHOD ForceDBClosed(void);
|
||||
NS_IMETHOD Delete(void);
|
||||
NS_IMETHOD DeleteSubFolders(nsISupportsArray *folders, nsIMsgWindow *msgWindow);
|
||||
NS_IMETHOD CreateStorageIfMissing(nsIUrlListener* urlListener);
|
||||
NS_IMETHOD PropagateDelete(nsIMsgFolder *folder, PRBool deleteStorage);
|
||||
NS_IMETHOD RecursiveDelete(PRBool deleteStorage);
|
||||
NS_IMETHOD CreateSubfolder(const PRUnichar *folderName);
|
||||
|
|
|
@ -157,7 +157,7 @@ CopyListener::SetMsgComposeAndSendObject(nsMsgComposeAndSend *obj)
|
|||
// to listen for message copy completion and eventually notify the caller
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsMsgCopy, NS_GET_IID(nsMsgCopy));
|
||||
NS_IMPL_ISUPPORTS(nsMsgCopy, NS_GET_IID(nsIUrlListener))
|
||||
|
||||
nsMsgCopy::nsMsgCopy()
|
||||
{
|
||||
|
@ -184,6 +184,7 @@ nsMsgCopy::StartCopyOperation(nsIMsgIdentity *aUserIdentity,
|
|||
{
|
||||
nsCOMPtr<nsIMsgFolder> dstFolder;
|
||||
PRBool isDraft = PR_FALSE;
|
||||
PRBool waitForUrl = PR_FALSE;
|
||||
nsresult rv;
|
||||
|
||||
if (!aMsgSendObj)
|
||||
|
@ -198,7 +199,7 @@ nsMsgCopy::StartCopyOperation(nsIMsgIdentity *aUserIdentity,
|
|||
//
|
||||
if (aMode == nsIMsgSend::nsMsgQueueForLater) // QueueForLater (Outbox)
|
||||
{
|
||||
rv = GetUnsentMessagesFolder(aUserIdentity, getter_AddRefs(dstFolder));
|
||||
rv = GetUnsentMessagesFolder(aUserIdentity, getter_AddRefs(dstFolder), &waitForUrl);
|
||||
isDraft = PR_FALSE;
|
||||
if (!dstFolder || NS_FAILED(rv)) {
|
||||
return NS_MSG_UNABLE_TO_SEND_LATER;
|
||||
|
@ -206,7 +207,7 @@ nsMsgCopy::StartCopyOperation(nsIMsgIdentity *aUserIdentity,
|
|||
}
|
||||
else if (aMode == nsIMsgSend::nsMsgSaveAsDraft) // SaveAsDraft (Drafts)
|
||||
{
|
||||
rv = GetDraftsFolder(aUserIdentity, getter_AddRefs(dstFolder));
|
||||
rv = GetDraftsFolder(aUserIdentity, getter_AddRefs(dstFolder), &waitForUrl);
|
||||
isDraft = PR_TRUE;
|
||||
if (!dstFolder || NS_FAILED(rv)) {
|
||||
return NS_MSG_UNABLE_TO_SAVE_DRAFT;
|
||||
|
@ -214,7 +215,7 @@ nsMsgCopy::StartCopyOperation(nsIMsgIdentity *aUserIdentity,
|
|||
}
|
||||
else if (aMode == nsIMsgSend::nsMsgSaveAsTemplate) // SaveAsTemplate (Templates)
|
||||
{
|
||||
rv = GetTemplatesFolder(aUserIdentity, getter_AddRefs(dstFolder));
|
||||
rv = GetTemplatesFolder(aUserIdentity, getter_AddRefs(dstFolder), &waitForUrl);
|
||||
isDraft = PR_FALSE;
|
||||
if (!dstFolder || NS_FAILED(rv)) {
|
||||
return NS_MSG_UNABLE_TO_SAVE_TEMPLATE;
|
||||
|
@ -222,7 +223,7 @@ nsMsgCopy::StartCopyOperation(nsIMsgIdentity *aUserIdentity,
|
|||
}
|
||||
else // SaveInSentFolder (Sent) - nsMsgDeliverNow
|
||||
{
|
||||
rv = GetSentFolder(aUserIdentity, getter_AddRefs(dstFolder));
|
||||
rv = GetSentFolder(aUserIdentity, getter_AddRefs(dstFolder), &waitForUrl);
|
||||
isDraft = PR_FALSE;
|
||||
if (!dstFolder || NS_FAILED(rv)) {
|
||||
return NS_MSG_COULDNT_OPEN_FCC_FOLDER;
|
||||
|
@ -230,7 +231,19 @@ nsMsgCopy::StartCopyOperation(nsIMsgIdentity *aUserIdentity,
|
|||
}
|
||||
|
||||
mMode = aMode;
|
||||
rv = DoCopy(aFileSpec, dstFolder, aMsgToReplace, isDraft, nsnull, aMsgSendObj);
|
||||
if (!waitForUrl)
|
||||
{
|
||||
rv = DoCopy(aFileSpec, dstFolder, aMsgToReplace, isDraft, nsnull, aMsgSendObj);
|
||||
}
|
||||
else
|
||||
{
|
||||
mFileSpec = aFileSpec;
|
||||
mDstFolder = dstFolder;
|
||||
mMsgToReplace = aMsgToReplace;
|
||||
mIsDraft = isDraft;
|
||||
mMsgSendObj = aMsgSendObj;
|
||||
// cache info needed for DoCopy and call DoCopy when OnStopUrl is called.
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -305,30 +318,103 @@ nsMsgCopy::DoCopy(nsIFileSpec *aDiskFile, nsIMsgFolder *dstFolder,
|
|||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsMsgCopy::GetUnsentMessagesFolder(nsIMsgIdentity *userIdentity, nsIMsgFolder **folder)
|
||||
// nsIUrlListener methods
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMsgCopy::OnStartRunningUrl(nsIURI * aUrl)
|
||||
{
|
||||
return LocateMessageFolder(userIdentity, nsIMsgSend::nsMsgQueueForLater, mSavePref, folder);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMsgCopy::OnStopRunningUrl(nsIURI * aUrl, nsresult aExitCode)
|
||||
{
|
||||
nsresult rv = aExitCode;
|
||||
if (NS_SUCCEEDED(aExitCode))
|
||||
{
|
||||
rv = DoCopy(mFileSpec, mDstFolder, mMsgToReplace, mIsDraft, nsnull, mMsgSendObj);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsMsgCopy::GetUnsentMessagesFolder(nsIMsgIdentity *userIdentity, nsIMsgFolder **folder, PRBool *waitForUrl)
|
||||
{
|
||||
nsresult ret = LocateMessageFolder(userIdentity, nsIMsgSend::nsMsgQueueForLater, mSavePref, folder);
|
||||
CreateIfMissing(folder, waitForUrl);
|
||||
return ret;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsMsgCopy::GetDraftsFolder(nsIMsgIdentity *userIdentity, nsIMsgFolder **folder)
|
||||
nsMsgCopy::GetDraftsFolder(nsIMsgIdentity *userIdentity, nsIMsgFolder **folder, PRBool *waitForUrl)
|
||||
{
|
||||
return LocateMessageFolder(userIdentity, nsIMsgSend::nsMsgSaveAsDraft, mSavePref, folder);
|
||||
nsresult ret = LocateMessageFolder(userIdentity, nsIMsgSend::nsMsgSaveAsDraft, mSavePref, folder);
|
||||
CreateIfMissing(folder, waitForUrl);
|
||||
return ret;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsMsgCopy::GetTemplatesFolder(nsIMsgIdentity *userIdentity, nsIMsgFolder **folder)
|
||||
nsMsgCopy::GetTemplatesFolder(nsIMsgIdentity *userIdentity, nsIMsgFolder **folder, PRBool *waitForUrl)
|
||||
{
|
||||
return LocateMessageFolder(userIdentity, nsIMsgSend::nsMsgSaveAsTemplate, mSavePref, folder);
|
||||
nsresult ret = LocateMessageFolder(userIdentity, nsIMsgSend::nsMsgSaveAsTemplate, mSavePref, folder);
|
||||
CreateIfMissing(folder, waitForUrl);
|
||||
return ret;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsMsgCopy::GetSentFolder(nsIMsgIdentity *userIdentity, nsIMsgFolder **folder)
|
||||
nsMsgCopy::GetSentFolder(nsIMsgIdentity *userIdentity, nsIMsgFolder **folder, PRBool *waitForUrl)
|
||||
{
|
||||
return LocateMessageFolder(userIdentity, nsIMsgSend::nsMsgDeliverNow, mSavePref, folder);
|
||||
nsresult ret = LocateMessageFolder(userIdentity, nsIMsgSend::nsMsgDeliverNow, mSavePref, folder);
|
||||
CreateIfMissing(folder, waitForUrl);
|
||||
return ret;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsMsgCopy::CreateIfMissing(nsIMsgFolder **folder, PRBool *waitForUrl)
|
||||
{
|
||||
nsresult ret = NS_OK;
|
||||
if (folder && *folder)
|
||||
{
|
||||
nsCOMPtr <nsIFolder> parent;
|
||||
(*folder)->GetParent(getter_AddRefs(parent));
|
||||
if (!parent)
|
||||
{
|
||||
nsCOMPtr <nsIFileSpec> folderPath;
|
||||
// for local folders, path is to the berkeley mailbox.
|
||||
// for imap folders, path needs to have .msf appended to the name
|
||||
(*folder)->GetPath(getter_AddRefs(folderPath));
|
||||
if (folderPath)
|
||||
{
|
||||
PRBool isImapFolder = !nsCRT::strncasecmp(mSavePref, "imap:", 5);
|
||||
if (isImapFolder)
|
||||
{
|
||||
nsXPIDLCString leafName;
|
||||
|
||||
folderPath->GetLeafName(getter_Copies(leafName));
|
||||
|
||||
nsCString fullLeafName(leafName);
|
||||
|
||||
// Append .msf (msg summary file) this is what windows will want.
|
||||
// Mac and Unix can decide for themselves.
|
||||
|
||||
fullLeafName.Append(".msf"); // message summary file
|
||||
folderPath->SetLeafName(fullLeafName);
|
||||
}
|
||||
PRBool exists;
|
||||
folderPath->Exists(&exists);
|
||||
if (!exists)
|
||||
{
|
||||
(*folder)->CreateStorageIfMissing(this);
|
||||
if (isImapFolder)
|
||||
*waitForUrl = PR_TRUE;
|
||||
|
||||
ret = NS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
// Utility Functions for MsgFolders
|
||||
////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -75,7 +75,7 @@ private:
|
|||
// This is a class that deals with processing remote attachments. It implements
|
||||
// an nsIStreamListener interface to deal with incoming data
|
||||
//
|
||||
class nsMsgCopy : public nsISupports
|
||||
class nsMsgCopy : public nsIUrlListener
|
||||
{
|
||||
public:
|
||||
static const nsIID& GetIID() { static nsIID iid = NS_IMSGCOPY_IID; return iid; }
|
||||
|
@ -85,6 +85,8 @@ public:
|
|||
|
||||
// nsISupports interface
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIURLLISTENER
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Object methods...
|
||||
|
@ -102,10 +104,11 @@ public:
|
|||
nsIMsgWindow *msgWindow,
|
||||
nsMsgComposeAndSend *aMsgSendObj);
|
||||
|
||||
nsresult GetUnsentMessagesFolder(nsIMsgIdentity *userIdentity, nsIMsgFolder **msgFolder);
|
||||
nsresult GetDraftsFolder(nsIMsgIdentity *userIdentity, nsIMsgFolder **msgFolder);
|
||||
nsresult GetTemplatesFolder(nsIMsgIdentity *userIdentity, nsIMsgFolder **msgFolder);
|
||||
nsresult GetSentFolder(nsIMsgIdentity *userIdentity, nsIMsgFolder **msgFolder);
|
||||
nsresult GetUnsentMessagesFolder(nsIMsgIdentity *userIdentity, nsIMsgFolder **msgFolder, PRBool *waitForUrl);
|
||||
nsresult GetDraftsFolder(nsIMsgIdentity *userIdentity, nsIMsgFolder **msgFolder, PRBool *waitForUrl);
|
||||
nsresult GetTemplatesFolder(nsIMsgIdentity *userIdentity, nsIMsgFolder **msgFolder, PRBool *waitForUrl);
|
||||
nsresult GetSentFolder(nsIMsgIdentity *userIdentity, nsIMsgFolder **msgFolder, PRBool *waitForUrl);
|
||||
nsresult CreateIfMissing(nsIMsgFolder **folder, PRBool *waitForUrl);
|
||||
|
||||
|
||||
//
|
||||
|
@ -114,6 +117,10 @@ public:
|
|||
nsIFileSpec *mFileSpec; // the file we are sending...
|
||||
nsMsgDeliverMode mMode;
|
||||
nsCOMPtr<CopyListener> mCopyListener;
|
||||
nsCOMPtr<nsIMsgFolder> mDstFolder;
|
||||
nsCOMPtr<nsIMessage> mMsgToReplace;
|
||||
PRBool mIsDraft;
|
||||
nsMsgComposeAndSend *mMsgSendObj;
|
||||
char *mSavePref;
|
||||
};
|
||||
|
||||
|
|
|
@ -3289,7 +3289,7 @@ nsMsgComposeAndSend::NotifyListenersOnStopCopy(nsresult aStatus)
|
|||
// This is one per copy so make sure we clean this up first.
|
||||
if (mCopyObj)
|
||||
{
|
||||
delete mCopyObj;
|
||||
NS_RELEASE(mCopyObj);
|
||||
mCopyObj = nsnull;
|
||||
}
|
||||
|
||||
|
@ -4118,7 +4118,7 @@ nsMsgComposeAndSend::StartMessageCopyOperation(nsIFileSpec *aFileSpec,
|
|||
mCopyObj = new nsMsgCopy();
|
||||
if (!mCopyObj)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(mCopyObj);
|
||||
//
|
||||
// Actually, we need to pick up the proper folder from the prefs and not
|
||||
// default to the default "Flagged" folder choices
|
||||
|
|
|
@ -53,6 +53,7 @@ interface nsIImapMailFolderSink : nsISupports {
|
|||
attribute boolean folderNeedsACLListed;
|
||||
attribute boolean folderNeedsSubscribing;
|
||||
attribute boolean folderNeedsAdded;
|
||||
attribute boolean folderVerifiedOnline;
|
||||
string GetOnlineDelimiter();
|
||||
// Tell mail master about the newly selected mailbox
|
||||
void UpdateImapMailboxInfo(in nsIImapProtocol aProtocol,
|
||||
|
|
|
@ -205,6 +205,16 @@ interface nsIImapService : nsISupports
|
|||
in wstring mailboxName,
|
||||
in nsIUrlListener aUrlListener);
|
||||
|
||||
// this method will first check if the folder exists but is
|
||||
// not subscribed to, in which case it will subscribe to the folder.
|
||||
// otherwise, it will try to create the folder. It will try to do this
|
||||
// with one url.
|
||||
nsIURI ensureFolderExists(in nsIEventQueue aClientEventQueue,
|
||||
in nsIMsgFolder aParentFolder,
|
||||
in wstring aLeafName,
|
||||
in nsIUrlListener aUrlListener);
|
||||
|
||||
|
||||
void buildSubscribeDatasource(in nsIImapIncomingServer aServer, in nsIMsgWindow aMsgWindow);
|
||||
void buildSubscribeDatasourceWithPath(in nsIImapIncomingServer aServer, in nsIMsgWindow aMsgWindow, in string folderPath);
|
||||
};
|
||||
|
|
|
@ -86,6 +86,7 @@ interface nsIImapUrl : nsISupports
|
|||
attribute boolean mimePartSelectorDetected;
|
||||
attribute nsImapContentModifiedType contentModified;
|
||||
attribute boolean fetchPartsOnDemand; // set to true if we're fetching a msg for display and want to not download parts
|
||||
attribute boolean msgLoadingFromCache; // true if this msg load is coming from a cache, so we can know to mark it read
|
||||
attribute nsISupports copyState;
|
||||
attribute nsIFileSpec msgFileSpec;
|
||||
attribute nsIImapMockChannel mockChannel;
|
||||
|
|
|
@ -685,6 +685,59 @@ NS_IMETHODIMP nsImapMailFolder::RemoveSubFolder (nsIMsgFolder *which)
|
|||
return nsMsgFolder::DeleteSubFolders(folders, nsnull);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImapMailFolder::CreateStorageIfMissing(nsIUrlListener* urlListener)
|
||||
{
|
||||
nsresult status = NS_OK;
|
||||
nsCOMPtr <nsIFolder> parent;
|
||||
GetParent(getter_AddRefs(parent));
|
||||
nsCOMPtr <nsIMsgFolder> msgParent;
|
||||
if (parent)
|
||||
msgParent = do_QueryInterface(parent);
|
||||
// parent is probably not set because *this* was probably created by rdf
|
||||
// and not by folder discovery. So, we have to compute the parent.
|
||||
if (!msgParent)
|
||||
{
|
||||
nsCAutoString folderName = mURI;
|
||||
|
||||
nsCAutoString uri;
|
||||
|
||||
PRInt32 leafPos = folderName.RFindChar('/');
|
||||
|
||||
nsCAutoString parentName(folderName);
|
||||
|
||||
if (leafPos > 0)
|
||||
{
|
||||
// If there is a hierarchy, there is a parent.
|
||||
// Don't strip off slash if it's the first character
|
||||
parentName.Truncate(leafPos);
|
||||
// get the corresponding RDF resource
|
||||
// RDF will create the folder resource if it doesn't already exist
|
||||
NS_WITH_SERVICE(nsIRDFService, rdf, kRDFServiceCID, &status);
|
||||
if (NS_FAILED(status)) return status;
|
||||
nsCOMPtr<nsIRDFResource> resource;
|
||||
status = rdf->GetResource(parentName, getter_AddRefs(resource));
|
||||
if (NS_FAILED(status)) return status;
|
||||
|
||||
msgParent = do_QueryInterface(resource, &status);
|
||||
}
|
||||
}
|
||||
if (msgParent)
|
||||
{
|
||||
nsXPIDLString folderName;
|
||||
GetName(getter_Copies(folderName));
|
||||
nsresult rv;
|
||||
NS_WITH_SERVICE(nsIImapService, imapService, kCImapService, &rv);
|
||||
if (NS_SUCCEEDED(rv) && imapService)
|
||||
{
|
||||
nsCOMPtr <nsIURI> uri;
|
||||
|
||||
imapService->EnsureFolderExists(m_eventQueue, msgParent, folderName, urlListener, getter_AddRefs(uri));
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP nsImapMailFolder::GetVerifiedAsOnlineFolder(PRBool *aVerifiedAsOnlineFolder)
|
||||
{
|
||||
|
@ -4208,6 +4261,20 @@ NS_IMETHODIMP nsImapMailFolder::SetFolderNeedsAdded(PRBool bVal)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImapMailFolder::GetFolderVerifiedOnline(PRBool *bVal)
|
||||
{
|
||||
if (!bVal)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
*bVal = m_verifiedAsOnlineFolder;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImapMailFolder::SetFolderVerifiedOnline(PRBool bVal)
|
||||
{
|
||||
m_verifiedAsOnlineFolder = bVal;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImapMailFolder::PerformExpand(nsIMsgWindow *aMsgWindow)
|
||||
{
|
||||
nsresult rv;
|
||||
|
|
|
@ -120,6 +120,7 @@ public:
|
|||
|
||||
NS_IMETHOD CreateSubfolder(const PRUnichar *folderName);
|
||||
NS_IMETHOD AddSubfolderWithPath(nsAutoString *name, nsIFileSpec *dbPath, nsIMsgFolder **child);
|
||||
NS_IMETHODIMP CreateStorageIfMissing(nsIUrlListener* urlListener);
|
||||
|
||||
NS_IMETHOD Compact();
|
||||
NS_IMETHOD EmptyTrash(nsIMsgWindow *msgWindow, nsIUrlListener *aListener);
|
||||
|
|
|
@ -4734,6 +4734,31 @@ void nsImapProtocol::OnCreateFolder(const char * aSourceMailbox)
|
|||
FolderNotCreated(aSourceMailbox);
|
||||
}
|
||||
|
||||
void nsImapProtocol::OnEnsureExistsFolder(const char * aSourceMailbox)
|
||||
{
|
||||
|
||||
List(aSourceMailbox, PR_FALSE); // how to tell if that succeeded?
|
||||
PRBool exists = PR_FALSE;
|
||||
if (m_imapMailFolderSink)
|
||||
m_imapMailFolderSink->GetFolderVerifiedOnline(&exists);
|
||||
|
||||
if (exists)
|
||||
{
|
||||
Subscribe(aSourceMailbox);
|
||||
}
|
||||
else
|
||||
{
|
||||
PRBool created = CreateMailboxRespectingSubscriptions(aSourceMailbox);
|
||||
if (created)
|
||||
{
|
||||
List(aSourceMailbox, PR_FALSE);
|
||||
}
|
||||
}
|
||||
if (!GetServerStateParser().LastCommandSuccessful())
|
||||
FolderNotCreated(aSourceMailbox);
|
||||
}
|
||||
|
||||
|
||||
void nsImapProtocol::OnSubscribe(const char * sourceMailbox)
|
||||
{
|
||||
Subscribe(sourceMailbox);
|
||||
|
@ -6058,6 +6083,10 @@ void nsImapProtocol::ProcessAuthenticatedStateURL()
|
|||
sourceMailbox = OnCreateServerSourceFolderPathString();
|
||||
OnCreateFolder(sourceMailbox);
|
||||
break;
|
||||
case nsIImapUrl::nsImapEnsureExistsFolder:
|
||||
sourceMailbox = OnCreateServerSourceFolderPathString();
|
||||
OnEnsureExistsFolder(sourceMailbox);
|
||||
break;
|
||||
case nsIImapUrl::nsImapDiscoverChildrenUrl:
|
||||
{
|
||||
char *canonicalParent = nsnull;
|
||||
|
@ -6795,7 +6824,12 @@ NS_IMETHODIMP nsImapMockChannel::AsyncRead(nsIStreamListener *listener, nsISuppo
|
|||
NS_RELEASE(cacheListener);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) // ONLY if we succeeded in actually starting the read should we return
|
||||
{
|
||||
// if the msg is unread, we should mark it read on the server. This lets
|
||||
// the code running this url we're loading from the cache, if it cares.
|
||||
imapUrl->SetMsgLoadingFromCache(PR_TRUE);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -453,6 +453,7 @@ private:
|
|||
char * OnCreateServerSourceFolderPathString();
|
||||
char * OnCreateServerDestinationFolderPathString();
|
||||
void OnCreateFolder(const char * aSourceMailbox);
|
||||
void OnEnsureExistsFolder(const char * aSourceMailbox);
|
||||
void OnSubscribe(const char * aSourceMailbox);
|
||||
void OnUnsubscribe(const char * aSourceMailbox);
|
||||
void RefreshACLForFolderIfNecessary(const char * mailboxName);
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
#include "nsMsgBaseCID.h"
|
||||
#include "nsMsgFolderFlags.h"
|
||||
#include "nsISubscribableServer.h"
|
||||
#include "nsIMessage.h"
|
||||
|
||||
#define PREF_MAIL_ROOT_IMAP "mail.root.imap"
|
||||
|
||||
|
@ -469,8 +470,50 @@ NS_IMETHODIMP nsImapService::DisplayMessage(const char* aMessageURI,
|
|||
imapUrl->SetFetchPartsOnDemand(PR_TRUE);
|
||||
msgurl->SetAddToMemoryCache(PR_FALSE);
|
||||
}
|
||||
PRBool msgLoadingFromCache = PR_FALSE;
|
||||
rv = FetchMessage(imapUrl, nsIImapUrl::nsImapMsgFetch, folder, imapMessageSink,
|
||||
aURL, aDisplayConsumer, msgKey, PR_TRUE);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
imapUrl->GetMsgLoadingFromCache(&msgLoadingFromCache);
|
||||
// we're reading this msg from the cache - mark it read on the server.
|
||||
if (msgLoadingFromCache)
|
||||
{
|
||||
nsCOMPtr <nsIMsgDatabase> database;
|
||||
if (NS_SUCCEEDED(folder->GetMsgDatabase(nsnull, getter_AddRefs(database))) && database)
|
||||
{
|
||||
PRBool msgRead = PR_TRUE;
|
||||
database->IsRead(key, &msgRead);
|
||||
if (!msgRead)
|
||||
{
|
||||
nsCOMPtr<nsISupportsArray> messages;
|
||||
rv = NS_NewISupportsArray(getter_AddRefs(messages));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
NS_WITH_SERVICE(nsIRDFService, rdfService, kRDFServiceCID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
nsCOMPtr<nsIRDFResource> msgResource;
|
||||
nsCOMPtr<nsIMessage> message;
|
||||
rv = rdfService->GetResource(aMessageURI,
|
||||
getter_AddRefs(msgResource));
|
||||
if(NS_SUCCEEDED(rv))
|
||||
{
|
||||
rv = msgResource->QueryInterface(NS_GET_IID(nsIMessage),
|
||||
getter_AddRefs(message));
|
||||
if (NS_SUCCEEDED(rv) && message)
|
||||
{
|
||||
nsCOMPtr<nsISupports> msgSupport(do_QueryInterface(message, &rv));
|
||||
if (msgSupport)
|
||||
{
|
||||
messages->AppendElement(msgSupport);
|
||||
folder->MarkMessagesRead(messages, PR_TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
|
@ -1971,7 +2014,7 @@ nsImapService::CreateFolder(nsIEventQueue* eventQueue, nsIMsgFolder* parent,
|
|||
nsIUrlListener* urlListener, nsIURI** url)
|
||||
{
|
||||
NS_ASSERTION(eventQueue && parent && newFolderName && *newFolderName,
|
||||
"Oops ... [RenameLeaf] null pointers");
|
||||
"Oops ... [CreateFolder] null pointers");
|
||||
if (!eventQueue || !parent || !newFolderName || !*newFolderName)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
|
@ -2013,6 +2056,55 @@ nsImapService::CreateFolder(nsIEventQueue* eventQueue, nsIMsgFolder* parent,
|
|||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsImapService::EnsureFolderExists(nsIEventQueue* eventQueue, nsIMsgFolder* parent,
|
||||
const PRUnichar* newFolderName,
|
||||
nsIUrlListener* urlListener, nsIURI** url)
|
||||
{
|
||||
NS_ASSERTION(eventQueue && parent && newFolderName && *newFolderName,
|
||||
"Oops ... [EnsureExists] null pointers");
|
||||
if (!eventQueue || !parent || !newFolderName || !*newFolderName)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsCOMPtr<nsIImapUrl> imapUrl;
|
||||
nsCAutoString urlSpec;
|
||||
nsresult rv;
|
||||
|
||||
PRUnichar hierarchySeparator = GetHierarchyDelimiter(parent);
|
||||
rv = CreateStartOfImapUrl(nsnull, getter_AddRefs(imapUrl), parent, urlListener, urlSpec, hierarchySeparator);
|
||||
if (NS_SUCCEEDED(rv) && imapUrl)
|
||||
{
|
||||
rv = SetImapUrlSink(parent, imapUrl);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
nsCOMPtr<nsIURI> uri = do_QueryInterface(imapUrl);
|
||||
|
||||
nsXPIDLCString folderName;
|
||||
GetFolderName(parent, getter_Copies(folderName));
|
||||
urlSpec.Append("/ensureExists>");
|
||||
urlSpec.AppendWithConversion(hierarchySeparator);
|
||||
if ((const char *) folderName && nsCRT::strlen(folderName) > 0)
|
||||
{
|
||||
urlSpec.Append((const char *) folderName);
|
||||
urlSpec.AppendWithConversion(hierarchySeparator);
|
||||
}
|
||||
char *utfNewName = CreateUtf7ConvertedStringFromUnicode( newFolderName);
|
||||
char *escapedFolderName = nsEscape(utfNewName, url_Path);
|
||||
urlSpec.Append(escapedFolderName);
|
||||
nsCRT::free(escapedFolderName);
|
||||
nsCRT::free(utfNewName);
|
||||
|
||||
rv = uri->SetSpec((char*) urlSpec.GetBuffer());
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = GetImapConnectionAndLoadUrl(eventQueue, imapUrl,
|
||||
nsnull,
|
||||
url);
|
||||
} // if (NS_SUCCEEDED(rv))
|
||||
} // if (NS_SUCCEEDED(rv) && imapUrl)
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsImapService::ListFolder(nsIEventQueue* aClientEventQueue,
|
||||
nsIMsgFolder* aImapMailFolder,
|
||||
|
|
|
@ -66,6 +66,7 @@ nsImapUrl::nsImapUrl()
|
|||
m_mimePartSelectorDetected = PR_FALSE;
|
||||
m_allowContentChange = PR_TRUE; // assume we can do MPOD.
|
||||
m_fetchPartsOnDemand = PR_FALSE; // but assume we're not doing it :-)
|
||||
m_msgLoadingFromCache = PR_FALSE;
|
||||
m_contentModified = IMAP_CONTENT_NOT_MODIFIED;
|
||||
m_validUrl = PR_TRUE; // assume the best.
|
||||
m_flags = 0;
|
||||
|
@ -542,6 +543,11 @@ void nsImapUrl::ParseImapPart(char *imapPartOfUrl)
|
|||
m_imapAction = nsImapCreateFolder;
|
||||
ParseFolderPath(&m_sourceCanonicalFolderPathSubString);
|
||||
}
|
||||
else if (!nsCRT::strcasecmp(m_urlidSubString, "ensureExists"))
|
||||
{
|
||||
m_imapAction = nsImapEnsureExistsFolder;
|
||||
ParseFolderPath(&m_sourceCanonicalFolderPathSubString);
|
||||
}
|
||||
else if (!nsCRT::strcasecmp(m_urlidSubString, "discoverchildren"))
|
||||
{
|
||||
m_imapAction = nsImapDiscoverChildrenUrl;
|
||||
|
@ -1067,6 +1073,7 @@ NS_IMETHODIMP nsImapUrl::GetUri(char** aURI)
|
|||
|
||||
NS_IMPL_GETSET(nsImapUrl, AddDummyEnvelope, PRBool, m_addDummyEnvelope);
|
||||
NS_IMPL_GETSET(nsImapUrl, CanonicalLineEnding, PRBool, m_canonicalLineEnding);
|
||||
NS_IMPL_GETSET(nsImapUrl, MsgLoadingFromCache, PRBool, m_msgLoadingFromCache);
|
||||
|
||||
NS_IMETHODIMP nsImapUrl::SetMessageFile(nsIFileSpec * aFileSpec)
|
||||
{
|
||||
|
|
|
@ -93,6 +93,7 @@ protected:
|
|||
PRBool m_mimePartSelectorDetected;
|
||||
PRBool m_allowContentChange; // if PR_FALSE, we can't use Mime parts on demand
|
||||
PRBool m_fetchPartsOnDemand; // if PR_TRUE, we should fetch leave parts on server.
|
||||
PRBool m_msgLoadingFromCache; // if PR_TRUE, we might need to mark read on server
|
||||
nsImapContentModifiedType m_contentModified;
|
||||
PRInt32 m_discoveryDepth;
|
||||
|
||||
|
|
|
@ -911,6 +911,52 @@ nsresult nsMsgLocalMailFolder::CreateDirectoryForFolder(nsFileSpec &path)
|
|||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgLocalMailFolder::CreateStorageIfMissing(nsIUrlListener* urlListener)
|
||||
{
|
||||
nsresult status = NS_OK;
|
||||
nsCOMPtr <nsIFolder> parent;
|
||||
GetParent(getter_AddRefs(parent));
|
||||
nsCOMPtr <nsIMsgFolder> msgParent;
|
||||
if (parent)
|
||||
msgParent = do_QueryInterface(parent);
|
||||
// parent is probably not set because *this* was probably created by rdf
|
||||
// and not by folder discovery. So, we have to compute the parent.
|
||||
if (!msgParent)
|
||||
{
|
||||
nsCAutoString folderName = mURI;
|
||||
|
||||
nsCAutoString uri;
|
||||
|
||||
PRInt32 leafPos = folderName.RFindChar('/');
|
||||
|
||||
nsCAutoString parentName(folderName);
|
||||
|
||||
if (leafPos > 0)
|
||||
{
|
||||
// If there is a hierarchy, there is a parent.
|
||||
// Don't strip off slash if it's the first character
|
||||
parentName.Truncate(leafPos);
|
||||
// get the corresponding RDF resource
|
||||
// RDF will create the folder resource if it doesn't already exist
|
||||
NS_WITH_SERVICE(nsIRDFService, rdf, kRDFServiceCID, &status);
|
||||
if (NS_FAILED(status)) return status;
|
||||
nsCOMPtr<nsIRDFResource> resource;
|
||||
status = rdf->GetResource(parentName, getter_AddRefs(resource));
|
||||
if (NS_FAILED(status)) return status;
|
||||
|
||||
msgParent = do_QueryInterface(resource, &status);
|
||||
}
|
||||
}
|
||||
if (msgParent)
|
||||
|
||||
{
|
||||
nsXPIDLString folderName;
|
||||
GetName(getter_Copies(folderName));
|
||||
status = msgParent->CreateSubfolder(folderName);
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsMsgLocalMailFolder::CreateSubfolder(const PRUnichar *folderName)
|
||||
{
|
||||
|
|
|
@ -108,6 +108,7 @@ public:
|
|||
NS_IMETHOD EmptyTrash(nsIMsgWindow *msgWindow, nsIUrlListener *aListener);
|
||||
NS_IMETHOD Delete ();
|
||||
NS_IMETHOD DeleteSubFolders(nsISupportsArray *folders, nsIMsgWindow *msgWindow);
|
||||
NS_IMETHOD CreateStorageIfMissing(nsIUrlListener* urlListener);
|
||||
NS_IMETHOD Rename (const PRUnichar *aNewName);
|
||||
NS_IMETHOD Adopt(nsIMsgFolder *srcFolder, PRUint32 *outPos);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче