Fix for 21469. r=jefft. Deleting a message in a thread now goes to the next message and scrolls

to it so that you don't lose your place in the thread pane.  More work on 26456.  r=alecf.
Some performance improvements for loading folders by speeding up building up a uri.
This commit is contained in:
putterman%netscape.com 2000-02-16 00:39:23 +00:00
parent 704fc18e04
commit de272ba0ac
33 changed files with 376 additions and 81 deletions

View File

@ -41,4 +41,5 @@ interface nsICopyMessageListener : nsISupports
void CopyData(in nsIInputStream aIStream, in long aLength);
void EndMessage(in nsMsgKey key);
void EndCopy(in boolean copySucceeded);
void EndMove();
};

View File

@ -38,4 +38,5 @@ interface nsIFolderListener : nsISupports {
void OnItemPropertyFlagChanged(in nsISupports item, in nsIAtom property, in unsigned long oldFlag,
in unsigned long newFlag);
void OnFolderLoaded(in nsIFolder aFolder);
void OnDeleteOrMoveMessagesCompleted(in nsIFolder aFolder);
};

View File

@ -250,7 +250,7 @@ interface nsIMsgFolder : nsIFolder {
void deleteMessages(in nsISupportsArray message,
in nsIMsgWindow msgWindow,
in boolean deleteStorage);
in boolean deleteStorage, in boolean isMove);
void copyMessages(in nsIMsgFolder srcFolder, in nsISupportsArray messages,
in boolean isMove, in nsIMsgWindow msgWindow,

View File

@ -71,6 +71,7 @@ interface nsIMsgMailSession : nsISupports {
void NotifyFolderItemAdded(in nsISupports parentItem, in nsISupports item, in string viewString);
void NotifyFolderItemDeleted(in nsISupports parentItem, in nsISupports item, in string viewString);
void NotifyFolderLoaded(in nsIFolder folder);
void NotifyDeleteOrMoveMessagesCompleted(in nsIFolder folder);
void AddMsgWindow(in nsIMsgWindow msgWindow);
void RemoveMsgWindow(in nsIMsgWindow msgWindow);

View File

@ -252,11 +252,11 @@ function DropOnFolderTree(event)
//temperary for single mail window, not working when supporting multiple mail windows
messageTree = GetThreadTree();
var nextMessage = GetNextMessageAfterDelete(messageTree.selectedItems);
gNextMessageAfterDelete = nextMessage.getAttribute('id');
messenger.CopyMessages(treeDatabase,
sourceRescource,
targetNode, messageList, true);
SelectNextMessage(nextMessage);
}
}
else

View File

@ -68,6 +68,7 @@ var gCurrentLoadingFolderIsThreaded = false;
var gCurrentLoadingFolderSortID ="";
var gCurrentDisplayedMessage = null;
var gNextMessageAfterDelete = null;
// the folderListener object
var folderListener = {
@ -155,9 +156,51 @@ var folderListener = {
}
}
},
OnDeleteOrMoveMessagesCompleted :function(folder)
{
dump("In OnDeleteOrMoveMessagesCompleted\n");
if(IsCurrentLoadedFolder(folder))
{
msgNavigationService.EnsureDocumentIsLoaded(document);
dump("next message uri is " + gNextMessageAfterDelete + "\n");
var nextMessage = document.getElementById(gNextMessageAfterDelete);
if(!nextMessage)
dump("No next message after delete\n");
SelectNextMessage(nextMessage);
var threadTree = GetThreadTree();
if(threadTree)
threadTree.ensureElementIsVisible(nextMessage);
else
dump("No thread tree\n");
gNextMessageAfterDelete = null;
}
}
}
function IsCurrentLoadedFolder(folder)
{
msgfolder = folder.QueryInterface(Components.interfaces.nsIMsgFolder);
if(msgfolder)
{
dump("IsCurrentLoadedFolder: has msgFolder\n");
var folderResource = msgfolder.QueryInterface(Components.interfaces.nsIRDFResource);
if(folderResource)
{
dump("IsCurrentLoadedFolder: has folderResource\n");
var folderURI = folderResource.Value;
var currentLoadedFolder = GetThreadTreeFolder();
var currentURI = currentLoadedFolder.getAttribute('ref');
dump("IsCurrentLoadedFolder: folderURI = " + folderURI + "\n");
dump("IsCurrentLoadedFolder: currentURI = " + currentURI + "\n");
return(currentURI == folderURI);
}
}
return false;
}
/* Functions related to startup */
function OnLoadMessenger()
{
@ -179,7 +222,7 @@ function OnLoadMessenger()
//need to add to session before trying to load start folder otherwise listeners aren't
//set up correctly.
dump('Before load start folder\n');
loadStartFolder();
setTimeout("loadStartFolder();", 0);
// FIX ME - later we will be able to use onload from the overlay
OnLoadMsgHeaderPane();

View File

@ -405,7 +405,7 @@ function MsgDeleteMessage(fromToolbar)
//get the current folder
messenger.DeleteMessages(tree.database, srcFolder.resource, messageList);
SelectNextMessage(nextMessage);
gNextMessageAfterDelete = nextMessage.getAttribute('id');
}
}
@ -535,10 +535,10 @@ function MsgMoveMessage(destFolder)
}
else
{
gNextMessageAfterDelete = nextMessage.getAttribute('id');
messenger.CopyMessages(tree.database,
srcFolder.resource,
destFolder.resource, messageList, true);
SelectNextMessage(nextMessage);
}
}
}

View File

@ -105,7 +105,7 @@ static nsresult DeleteMessage(nsIURI *aURL, nsIMsgFolder *srcFolder)
nsCOMPtr<nsISupports> messageSupports(do_QueryInterface(message));
if(messageSupports)
messageArray->AppendElement(messageSupports);
rv = srcFolder->DeleteMessages(messageArray, nsnull, PR_TRUE);
rv = srcFolder->DeleteMessages(messageArray, nsnull, PR_TRUE, PR_TRUE);
}
return rv;
}
@ -192,7 +192,11 @@ NS_IMETHODIMP nsCopyMessageStreamListener::OnStopRequest(nsIChannel * aChannel,
// don't do this if we're moving to an imap folder - that's handled elsewhere.
nsCOMPtr <nsIMsgImapMailFolder> destImap = do_QueryInterface(mDestination);
if (!destImap)
{
rv = DeleteMessage(uri, mSrcFolder);
if(NS_SUCCEEDED(rv))
rv = mDestination->EndMove();
}
}
}
//Even if the above actions failed we probably still want to return NS_OK. There should probably

View File

@ -26,9 +26,6 @@
#include "nsMsgKeyArray.h"
#include "nspr.h"
// ******************** nsCopySource ******************
//
@ -446,7 +443,10 @@ nsMsgCopyService::NotifyCompletion(nsISupports* aSupport,
rv = DoNextCopy();
nsCopyRequest* copyRequest = FindRequest(aSupport, dstFolder);
if (copyRequest && copyRequest->m_processed)
{
ClearRequest(copyRequest, result);
}
return rv;
}

View File

@ -858,6 +858,11 @@ NS_IMETHODIMP nsMsgFolderDataSource::OnFolderLoaded(nsIFolder *folder)
return rv;
}
NS_IMETHODIMP nsMsgFolderDataSource::OnDeleteOrMoveMessagesCompleted(nsIFolder *folder)
{
nsresult rv = NS_OK;
return rv;
}
nsresult nsMsgFolderDataSource::createFolderNode(nsIMsgFolder* folder,
nsIRDFResource* property,
@ -1491,7 +1496,7 @@ nsresult nsMsgFolderDataSource::DoDeleteFromFolder(
rv = messageArray->Count(&cnt);
if (NS_FAILED(rv)) return rv;
if (cnt > 0)
rv = folder->DeleteMessages(messageArray, msgWindow, PR_FALSE);
rv = folder->DeleteMessages(messageArray, msgWindow, PR_FALSE, PR_FALSE);
rv = folderArray->Count(&cnt);
if (NS_FAILED(rv)) return rv;

View File

@ -259,6 +259,24 @@ NS_IMETHODIMP nsMsgMailSession::NotifyFolderLoaded(nsIFolder *folder)
}
NS_IMETHODIMP nsMsgMailSession::NotifyDeleteOrMoveMessagesCompleted(nsIFolder *folder)
{
nsresult rv;
PRUint32 count;
rv = mListeners->Count(&count);
if (NS_FAILED(rv)) return rv;
for(PRUint32 i = 0; i < count; i++)
{
nsCOMPtr<nsIFolderListener> listener = getter_AddRefs((nsIFolderListener*)mListeners->ElementAt(i));
listener->OnDeleteOrMoveMessagesCompleted(folder);
}
return NS_OK;
}
NS_IMETHODIMP nsMsgMailSession::AddMsgWindow(nsIMsgWindow *msgWindow)
{

View File

@ -734,6 +734,12 @@ NS_IMETHODIMP nsMsgMessageDataSource::OnFolderLoaded(nsIFolder *folder)
return rv;
}
NS_IMETHODIMP nsMsgMessageDataSource::OnDeleteOrMoveMessagesCompleted(nsIFolder *folder)
{
nsresult rv = NS_OK;
return rv;
}
nsresult nsMsgMessageDataSource::OnChangeStatus(nsIRDFResource *resource, PRUint32 oldFlag, PRUint32 newFlag)
{
OnChangeStatusString(resource, oldFlag, newFlag);

View File

@ -254,6 +254,11 @@ NS_IMETHODIMP nsMsgNotificationManager::OnFolderLoaded(nsIFolder *folder)
return rv;
}
NS_IMETHODIMP nsMsgNotificationManager::OnDeleteOrMoveMessagesCompleted(nsIFolder *folder)
{
nsresult rv = NS_OK;
return rv;
}
nsresult nsMsgNotificationManager::AddNewMailNotification(nsIMsgFolder *folder)
{

View File

@ -71,7 +71,8 @@ nsMsgFolder::nsMsgFolder(void)
mNumNewBiffMessages(0),
mHaveParsedURI(PR_FALSE),
mIsServerIsValid(PR_FALSE),
mIsServer(PR_FALSE)
mIsServer(PR_FALSE),
mBaseMessageURI(nsnull)
{
// NS_INIT_REFCNT(); done by superclass
@ -116,6 +117,9 @@ nsMsgFolder::~nsMsgFolder(void)
delete mListeners;
if(mBaseMessageURI)
nsCRT::free(mBaseMessageURI);
gInstanceCount--;
if (gInstanceCount <= 0) {
NS_IF_RELEASE(kTotalMessagesAtom);
@ -160,10 +164,20 @@ nsMsgFolder::Init(const char* aURI)
nsresult rv;
rv = nsRDFResource::Init(aURI);
if(NS_FAILED(rv))
return rv;
rv = CreateBaseMessageURI(aURI);
return NS_OK;
}
nsresult nsMsgFolder::CreateBaseMessageURI(const char *aURI)
{
//Each folder needs to implement this.
return NS_OK;
}
NS_IMETHODIMP nsMsgFolder::Shutdown(PRBool shutdownChildren)
{
return NS_OK;
@ -2122,6 +2136,24 @@ nsresult nsMsgFolder::NotifyFolderLoaded()
return NS_OK;
}
nsresult nsMsgFolder::NotifyDeleteOrMoveMessagesCompleted(nsIFolder *folder)
{
PRInt32 i;
for(i = 0; i < mListeners->Count(); i++)
{
//Folderlistener's aren't refcounted.
nsIFolderListener *listener = (nsIFolderListener*)mListeners->ElementAt(i);
listener->OnDeleteOrMoveMessagesCompleted(this);
}
//Notify listeners who listen to every folder
nsresult rv;
NS_WITH_SERVICE(nsIMsgMailSession, mailSession, kMsgMailSessionCID, &rv);
if(NS_SUCCEEDED(rv))
mailSession->NotifyDeleteOrMoveMessagesCompleted(folder);
return NS_OK;
}
nsresult
nsGetMailFolderSeparator(nsString& result)
{

View File

@ -230,12 +230,17 @@ protected:
nsresult NotifyItemDeleted(nsISupports *parentItem, nsISupports *item, const char* viewString);
nsresult NotifyFolderLoaded();
nsresult NotifyDeleteOrMoveMessagesCompleted(nsIFolder *folder);
// this is a little helper function that is not part of the public interface.
// we use it to get the IID of the incoming server for the derived folder.
// w/out a function like this we would have to implement GetServer in each
// derived folder class.
virtual const char* GetIncomingServerType() = 0;
virtual nsresult CreateBaseMessageURI(const char *aURI);
// helper routine to parse the URI and update member variables
nsresult parseURI(PRBool needServer=PR_FALSE);
@ -278,6 +283,7 @@ protected:
PRBool mIsServer;
nsString mName;
nsCOMPtr<nsIFileSpec> mPath;
char * mBaseMessageURI; //The uri with the message scheme
// static stuff for cross-instance objects like atoms
static PRInt32 gInstanceCount;

View File

@ -712,7 +712,7 @@ nsMsgSendLater::DeleteCurrentMessage()
nsCOMPtr<nsISupports> msgSupport = do_QueryInterface(mMessage, &res);
msgArray->InsertElementAt(msgSupport, 0);
res = mMessageFolder->DeleteMessages(msgArray, nsnull, PR_TRUE);
res = mMessageFolder->DeleteMessages(msgArray, nsnull, PR_TRUE, PR_FALSE);
if (NS_FAILED(res))
return NS_ERROR_FAILURE;

View File

@ -336,8 +336,10 @@ nsresult nsImapMailFolder::CreateSubFolders(nsFileSpec &path)
if (NS_SUCCEEDED(rv) && (const char *) onlineFullUtf7Name && nsCRT::strlen((const char *) onlineFullUtf7Name))
{
if (imapServer)
imapServer->CreatePRUnicharStringFromUTF7(onlineFullUtf7Name, getter_Copies(unicodeName));
// take the full unicode folder name and find the unicode leaf name.
currentFolderNameStr = unicodeName;
PRInt32 leafPos = currentFolderNameStr.RFindChar('/');
@ -1340,7 +1342,7 @@ nsImapMailFolder::AllocateUidStringFromKeyArray(nsMsgKeyArray &keyArray, nsCStri
NS_IMETHODIMP nsImapMailFolder::DeleteMessages(nsISupportsArray *messages,
nsIMsgWindow *msgWindow,
PRBool deleteStorage)
PRBool deleteStorage, PRBool isMove)
{
nsresult rv = NS_ERROR_FAILURE;
// *** jt - assuming delete is move to the trash folder for now
@ -1361,7 +1363,14 @@ NS_IMETHODIMP nsImapMailFolder::DeleteMessages(nsISupportsArray *messages,
if (NS_SUCCEEDED(rv))
{
if (mDatabase)
{
mDatabase->DeleteMessages(&srcKeyArray,NULL);
if(!isMove)
{
NotifyDeleteOrMoveMessagesCompleted(this);
}
}
return rv;
}
}
@ -1864,22 +1873,20 @@ NS_IMETHODIMP nsImapMailFolder::CreateMessageFromMsgDBHdr(nsIMsgDBHdr *msgDBHdr,
NS_WITH_SERVICE(nsIRDFService, rdfService, kRDFServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
char* msgURI = nsnull;
nsFileSpec path;
nsMsgKey key;
nsCOMPtr<nsIRDFResource> res;
rv = msgDBHdr->GetMessageKey(&key);
nsCAutoString msgURI;
if(NS_SUCCEEDED(rv))
rv = nsBuildImapMessageURI(mURI, key, &msgURI);
rv = nsBuildImapMessageURI(mBaseMessageURI, key, msgURI);
if(NS_SUCCEEDED(rv))
rv = rdfService->GetResource(msgURI, getter_AddRefs(res));
if(msgURI)
PR_smprintf_free(msgURI);
rv = rdfService->GetResource(msgURI.GetBuffer(), getter_AddRefs(res));
if(NS_SUCCEEDED(rv))
{
@ -2033,6 +2040,10 @@ NS_IMETHODIMP nsImapMailFolder::EndCopy(PRBool copySucceeded)
return rv;
}
NS_IMETHODIMP nsImapMailFolder::EndMove()
{
return NS_OK;
}
// this is the beginning of the next message copied
NS_IMETHODIMP nsImapMailFolder::StartMessage()
{
@ -2987,6 +2998,7 @@ nsImapMailFolder::OnStopRunningUrl(nsIURI *aUrl, nsresult aExitCode)
if (msgTxn)
msgTxn->GetSrcKeyArray(srcKeyArray);
srcDB->DeleteMessages(&srcKeyArray, nsnull);
NotifyDeleteOrMoveMessagesCompleted(srcFolder);
}
}
if (m_transactionManager)
@ -3408,7 +3420,7 @@ nsImapMailFolder::CopyNextStreamMessage(nsIImapProtocol* aProtocol,
if (NS_SUCCEEDED(rv) && srcFolder)
{
srcFolder->DeleteMessages(mailCopyState->m_messages, nsnull,
PR_FALSE);
PR_FALSE, PR_TRUE);
}
}
return rv;
@ -3846,6 +3858,14 @@ NS_IMETHODIMP nsImapMailFolder::MatchName(nsString *name, PRBool *matches)
return NS_OK;
}
nsresult nsImapMailFolder::CreateBaseMessageURI(const char *aURI)
{
nsresult rv;
rv = nsCreateImapBaseMessageURI(aURI, &mBaseMessageURI);
return rv;
}
NS_IMETHODIMP nsImapMailFolder::GetFolderNeedsSubscribing(PRBool *bVal)
{
if (!bVal)
@ -3891,3 +3911,4 @@ NS_IMETHODIMP nsImapMailFolder::SetFolderNeedsAdded(PRBool bVal)
m_folderNeedsAdded = bVal;
return NS_OK;
}

View File

@ -155,7 +155,7 @@ public:
nsIMsgDatabase **db);
NS_IMETHOD DeleteMessages(nsISupportsArray *messages,
nsIMsgWindow *msgWindow, PRBool
deleteStorage);
deleteStorage, PRBool isMove);
NS_IMETHOD CopyMessages(nsIMsgFolder *srcFolder,
nsISupportsArray* messages,
PRBool isMove, nsIMsgWindow *msgWindow,
@ -302,6 +302,9 @@ protected:
nsresult BuildIdsAndKeyArray(nsISupportsArray* messages,
nsCString& msgIds, nsMsgKeyArray& keyArray);
virtual nsresult CreateBaseMessageURI(const char *aURI);
PRBool m_initialized;
PRBool m_haveDiscoveredAllFolders;
PRBool m_haveReadNameFromDB;

View File

@ -747,9 +747,10 @@ NS_IMETHODIMP nsImapUrl::AllocateCanonicalPath(const char *serverPath, char onli
char *onlineDir = nsnull;
nsCOMPtr<nsIMsgIncomingServer> server;
NS_WITH_SERVICE(nsIImapHostSessionList, hostSessionList,
kCImapHostSessionListCID, &rv);
*allocatedPath = nsnull;
NS_WITH_SERVICE(nsIImapHostSessionList, hostSessionList,
kCImapHostSessionListCID, &rv);
*allocatedPath = nsnull;
if (onlineDelimiter == kOnlineHierarchySeparatorUnknown ||
onlineDelimiter == 0)
@ -974,9 +975,15 @@ nsImapUrl::GetURI(char** aURI)
fullFolderPath += '/';
fullFolderPath += theFile;
PR_FREEIF(hostName);
PR_FREEIF(hostName);
char * baseMessageURI;
nsCreateImapBaseMessageURI(fullFolderPath, &baseMessageURI);
nsCAutoString uriStr;
rv = nsBuildImapMessageURI(baseMessageURI, key, uriStr);
nsCRT::free(baseMessageURI);
*aURI = uriStr.ToNewCString();
return rv;
return nsBuildImapMessageURI(fullFolderPath, key, aURI);
}
return rv;

View File

@ -207,18 +207,39 @@ nsresult nsParseImapMessageURI(const char* uri, nsCString& folderURI, PRUint32 *
}
nsresult nsBuildImapMessageURI(const char *baseURI, PRUint32 key, char** uri)
nsresult nsBuildImapMessageURI(const char *baseURI, PRUint32 key, nsCString& uri)
{
if(!uri)
uri.Append(baseURI);
uri.Append('#');
char *keyStr = PR_smprintf("%u", key);
if(!keyStr)
return NS_ERROR_OUT_OF_MEMORY;
uri.Append(keyStr);
PR_smprintf_free(keyStr);
return NS_OK;
}
nsresult nsCreateImapBaseMessageURI(const char *baseURI, char **baseMessageURI)
{
if(!baseMessageURI)
return NS_ERROR_NULL_POINTER;
nsCAutoString tailURI(baseURI);
// chop off mailbox:/
if (tailURI.Find(kImapRootURI) == 0)
tailURI.Cut(0, PL_strlen(kImapRootURI));
nsCAutoString baseURIStr(kImapMessageRootURI);
baseURIStr += tailURI;
*uri = PR_smprintf("%s%s#%d", kImapMessageRootURI, (const char *) tailURI, key);
*baseMessageURI = baseURIStr.ToNewCString();
if(!*baseMessageURI)
return NS_ERROR_OUT_OF_MEMORY;
return NS_OK;
}
@ -501,6 +522,7 @@ CreateUtf7ConvertedStringFromUnicode(const PRUnichar * aSourceString)
return convertedString;
}
nsresult CreateUnicodeStringFromUtf7(const char *aSourceString, PRUnichar **aUnicodeStr)
{
if (!aUnicodeStr)

View File

@ -42,7 +42,10 @@ extern nsresult
nsParseImapMessageURI(const char* uri, nsCString& folderURI, PRUint32 *key);
extern nsresult
nsBuildImapMessageURI(const char *baseURI, PRUint32 key, char **uri);
nsBuildImapMessageURI(const char *baseURI, PRUint32 key, nsCString& uri);
extern nsresult
nsCreateImapBaseMessageURI(const char *baseURI, char **baseMessageURI);
void AllocateImapUidString(PRUint32 *msgUids, PRUint32 msgCount, nsCString &returnString);

View File

@ -68,6 +68,9 @@
#include "nsMsgTxn.h"
#include "nsIFileSpec.h"
#include "nsIMessenger.h"
#include "nsIMsgMailSession.h"
#include "nsMsgBaseCID.h"
static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
static NS_DEFINE_CID(kMailboxServiceCID, NS_MAILBOXSERVICE_CID);
@ -76,6 +79,8 @@ static NS_DEFINE_CID(kCPop3ServiceCID, NS_POP3SERVICE_CID);
static NS_DEFINE_CID(kCopyMessageStreamListenerCID, NS_COPYMESSAGESTREAMLISTENER_CID);
static NS_DEFINE_CID(kMsgCopyServiceCID, NS_MSGCOPYSERVICE_CID);
static NS_DEFINE_CID(kStandardUrlCID, NS_STANDARDURL_CID);
static NS_DEFINE_CID(kMsgMailSessionCID, NS_MSGMAILSESSION_CID);
//////////////////////////////////////////////////////////////////////////////
// nsLocal
@ -1096,7 +1101,7 @@ nsMsgLocalMailFolder::GetTrashFolder(nsIMsgFolder** result)
NS_IMETHODIMP
nsMsgLocalMailFolder::DeleteMessages(nsISupportsArray *messages,
nsIMsgWindow *msgWindow,
PRBool deleteStorage)
PRBool deleteStorage, PRBool isMove)
{
nsresult rv = NS_ERROR_FAILURE;
PRBool isTrashFolder = mFlags & MSG_FOLDER_FLAG_TRASH;
@ -1143,6 +1148,8 @@ nsMsgLocalMailFolder::DeleteMessages(nsISupportsArray *messages,
DeleteMessage(message, msgWindow, PR_TRUE);
}
}
if(!isMove)
NotifyDeleteOrMoveMessagesCompleted(this);
}
}
return rv;
@ -1442,21 +1449,19 @@ nsMsgLocalMailFolder::CreateMessageFromMsgDBHdr(nsIMsgDBHdr *msgDBHdr,
NS_WITH_SERVICE(nsIRDFService, rdfService, kRDFServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
char* msgURI = nsnull;
nsCAutoString msgURI;
nsMsgKey key;
nsCOMPtr<nsIRDFResource> resource;
rv = msgDBHdr->GetMessageKey(&key);
if(NS_SUCCEEDED(rv))
rv = nsBuildLocalMessageURI(mURI, key, &msgURI);
rv = nsBuildLocalMessageURI(mBaseMessageURI, key, msgURI);
if(NS_SUCCEEDED(rv))
{
rv = rdfService->GetResource(msgURI, getter_AddRefs(resource));
rv = rdfService->GetResource(msgURI.GetBuffer(), getter_AddRefs(resource));
}
if(msgURI)
PR_smprintf_free(msgURI);
if(NS_SUCCEEDED(rv))
{
@ -1778,21 +1783,62 @@ NS_IMETHODIMP nsMsgLocalMailFolder::EndCopy(PRBool copySucceeded)
{ // both CopyMessages() & CopyFileMessage() go here if they have
// done copying operation; notify completion to copy service
nsresult result;
NS_WITH_SERVICE(nsIMsgCopyService, copyService,
kMsgCopyServiceCID, &result);
if(!mCopyState->m_isMove)
{
NS_WITH_SERVICE(nsIMsgCopyService, copyService,
kMsgCopyServiceCID, &result);
if (NS_SUCCEEDED(result))
copyService->NotifyCompletion(mCopyState->m_srcSupport, this, rv);
if (NS_SUCCEEDED(result))
copyService->NotifyCompletion(mCopyState->m_srcSupport, this, rv);
if (mTxnMgr && NS_SUCCEEDED(rv) && mCopyState->m_undoMsgTxn)
mTxnMgr->Do(mCopyState->m_undoMsgTxn);
if (mTxnMgr && NS_SUCCEEDED(rv) && mCopyState->m_undoMsgTxn)
mTxnMgr->Do(mCopyState->m_undoMsgTxn);
ClearCopyState();
ClearCopyState();
}
}
return rv;
}
NS_IMETHODIMP nsMsgLocalMailFolder::EndMove()
{
nsresult result;
if (mCopyState->m_curCopyIndex == mCopyState->m_totalMsgCount)
{
NS_WITH_SERVICE(nsIMsgCopyService, copyService,
kMsgCopyServiceCID, &result);
if (NS_SUCCEEDED(result))
{
//Notify that a completion finished.
nsCOMPtr<nsIFolder> srcFolder = do_QueryInterface(mCopyState->m_srcSupport);
if(srcFolder)
{
nsresult rv;
NS_WITH_SERVICE(nsIMsgMailSession, mailSession, kMsgMailSessionCID, &rv);
if(NS_SUCCEEDED(rv))
mailSession->NotifyDeleteOrMoveMessagesCompleted(srcFolder);
}
//passing in NS_OK because we only get in here if copy portion succeeded
copyService->NotifyCompletion(mCopyState->m_srcSupport, this, NS_OK);
if (mTxnMgr && mCopyState->m_undoMsgTxn)
mTxnMgr->Do(mCopyState->m_undoMsgTxn);
ClearCopyState();
}
}
return NS_OK;
}
// this is the beginning of the next message copied
NS_IMETHODIMP nsMsgLocalMailFolder::StartMessage()
{
@ -2042,3 +2088,13 @@ nsMsgLocalMailFolder::GetIncomingServerType()
return "";
}
nsresult nsMsgLocalMailFolder::CreateBaseMessageURI(const char *aURI)
{
nsresult rv;
rv = nsCreateLocalBaseMessageURI(aURI, &mBaseMessageURI);
return rv;
}

View File

@ -125,7 +125,7 @@ public:
NS_IMETHOD DeleteMessages(nsISupportsArray *messages,
nsIMsgWindow *msgWindow, PRBool
deleteStorage);
deleteStorage, PRBool isMove);
NS_IMETHOD CopyMessages(nsIMsgFolder *srcFolder, nsISupportsArray* messages,
PRBool isMove, nsIMsgWindow *msgWindow,
nsIMsgCopyServiceListener* listener);
@ -167,6 +167,7 @@ protected:
nsresult InitCopyState(nsISupports* aSupport, nsISupportsArray* messages,
PRBool isMove, nsIMsgCopyServiceListener* listener);
void ClearCopyState();
virtual nsresult CreateBaseMessageURI(const char *aURI);
protected:
PRUint32 mExpungedBytes;

View File

@ -257,19 +257,40 @@ nsresult nsParseLocalMessageURI(const char* uri,
}
nsresult nsBuildLocalMessageURI(const char *baseURI, PRUint32 key, char** uri)
nsresult nsBuildLocalMessageURI(const char *baseURI, PRUint32 key, nsCString& uri)
{
if(!uri)
return NS_ERROR_NULL_POINTER;
// need to convert mailbox://hostname/.. to mailbox_message://hostname/..
uri.Append(baseURI);
uri.Append('#');
char *keyStr = PR_smprintf("%u", key);
if(!keyStr)
return NS_ERROR_OUT_OF_MEMORY;
uri.Append(keyStr);
PR_smprintf_free(keyStr);
return NS_OK;
}
nsresult nsCreateLocalBaseMessageURI(const char *baseURI, char **baseMessageURI)
{
if(!baseMessageURI)
return NS_ERROR_NULL_POINTER;
nsCAutoString tailURI(baseURI);
// chop off mailbox:/
if (tailURI.Find(kMailboxRootURI) == 0)
tailURI.Cut(0, PL_strlen(kMailboxRootURI));
nsCAutoString baseURIStr(kMailboxMessageRootURI);
baseURIStr += tailURI;
*baseMessageURI = baseURIStr.ToNewCString();
if(!*baseMessageURI)
return NS_ERROR_OUT_OF_MEMORY;
*uri = PR_smprintf("%s%s#%u", kMailboxMessageRootURI, tailURI.GetBuffer(), key);
return NS_OK;
}

View File

@ -37,6 +37,9 @@ nsresult
nsParseLocalMessageURI(const char* uri, nsCString& folderURI, PRUint32 *key);
nsresult
nsBuildLocalMessageURI(const char* baseURI, PRUint32 key, char** uri);
nsBuildLocalMessageURI(const char* baseURI, PRUint32 key, nsCString& uri);
nsresult
nsCreateLocalBaseMessageURI(const char *baseURI, char **baseMessageURI);
#endif //NS_LOCALUTILS_H

View File

@ -252,10 +252,15 @@ NS_IMETHODIMP nsMailboxUrl::GetURI(char ** aURI)
if (filePath)
{
char * baseuri = nsMailboxGetURI(m_file);
char * baseMessageURI;
nsCreateLocalBaseMessageURI(baseuri, &baseMessageURI);
char * uri = nsnull;
nsCAutoString uriStr;
nsFileSpec folder = *filePath;
nsBuildLocalMessageURI(baseuri, m_messageKey, &uri);
nsBuildLocalMessageURI(baseMessageURI, m_messageKey, uriStr);
PL_strfree(baseuri);
nsCRT::free(baseMessageURI);
uri = uriStr.ToNewCString();
*aURI = uri;
}
else

View File

@ -492,8 +492,11 @@ nsresult nsMailboxTestDriver::OnDisplayMessage(PRBool copyMessage)
// mscott - hacky....sprintf up a mailbox URI to represent the message.
char * uri = nsnull;
char * testString = PR_smprintf("%s%s", "mscott@dredd.mcom.com/", mailboxName);
rv = nsBuildLocalMessageURI(/* (const char *) filePath */ testString, msgKey, &uri);
nsCString uriStr;
char * testString = PR_smprintf("%s%s", "mailbox_message://mscott@dredd.mcom.com/", mailboxName);
rv = nsBuildLocalMessageURI(/* (const char *) filePath */ testString, msgKey, uriStr);
uri = uriStr.ToNewCString();
if (NS_SUCCEEDED(rv))
{
nsIMsgMessageService * messageService = nsnull;

View File

@ -55,7 +55,6 @@ nsMimeConverter::DecodeMimePartIIStr(const nsString& header,
PRBool eatContinuations)
{
char charsetCstr[kMAX_CSNAME+1];
char *encodedCstr = nsnull;
char *decodedCstr = nsnull;
nsresult res = NS_OK;

View File

@ -791,7 +791,8 @@ NS_IMETHODIMP nsMsgNewsFolder::GetSizeOnDisk(PRUint32 *size)
/* this is news, so remember that DeleteMessage is really CANCEL */
NS_IMETHODIMP nsMsgNewsFolder::DeleteMessages(nsISupportsArray *messages,
nsIMsgWindow *aMsgWindow, PRBool deleteStorage)
nsIMsgWindow *aMsgWindow, PRBool deleteStorage,
PRBool isMove)
{
nsresult rv = NS_OK;
@ -863,7 +864,6 @@ NS_IMETHODIMP nsMsgNewsFolder::CreateMessageFromMsgDBHdr(nsIMsgDBHdr *msgDBHdr,
NS_WITH_SERVICE(nsIRDFService, rdfService, kRDFServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
char* msgURI = nsnull;
nsFileSpec path;
nsMsgKey key;
nsCOMPtr <nsIRDFResource> res;
@ -871,13 +871,13 @@ NS_IMETHODIMP nsMsgNewsFolder::CreateMessageFromMsgDBHdr(nsIMsgDBHdr *msgDBHdr,
rv = msgDBHdr->GetMessageKey(&key);
if (NS_FAILED(rv)) return rv;
rv = nsBuildNewsMessageURI(mURI, key, &msgURI);
nsCAutoString msgURI;
rv = nsBuildNewsMessageURI(mBaseMessageURI, key, msgURI);
if (NS_FAILED(rv)) return rv;
rv = rdfService->GetResource(msgURI, getter_AddRefs(res));
rv = rdfService->GetResource(msgURI.GetBuffer(), getter_AddRefs(res));
PR_FREEIF(msgURI);
msgURI = nsnull;
if (NS_FAILED(rv)) return rv;
@ -1344,6 +1344,13 @@ nsMsgNewsFolder::GetGroupUsernameWithUI(const PRUnichar * aPromptMessage, const
return rv;
}
nsresult nsMsgNewsFolder::CreateBaseMessageURI(const char *aURI)
{
nsresult rv;
rv = nsCreateNewsBaseMessageURI(aURI, &mBaseMessageURI);
return rv;
}
NS_IMETHODIMP
nsMsgNewsFolder::GetNewsrcLine(char **newsrcLine)
@ -1441,3 +1448,4 @@ nsMsgNewsFolder::OnReadChanged(nsIDBChangeListener * aInstigator)
{
return SetNewsrcHasChanged(PR_TRUE);
}

View File

@ -84,7 +84,7 @@ public:
virtual nsresult GetDBFolderInfoAndDB(nsIDBFolderInfo **folderInfo, nsIMsgDatabase **db);
NS_IMETHOD DeleteMessages(nsISupportsArray *messages,
nsIMsgWindow *msgWindow, PRBool deleteStorage);
nsIMsgWindow *msgWindow, PRBool deleteStorage, PRBool isMove);
NS_IMETHOD CreateMessageFromMsgDBHdr(nsIMsgDBHdr *msgDBHdr, nsIMessage **message);
NS_IMETHOD GetNewMessages(nsIMsgWindow *aWindow);
@ -108,7 +108,8 @@ protected:
PRInt32 HandleLine(char *line, PRUint32 line_size);
virtual const char *GetIncomingServerType() {return "nntp";}
virtual nsresult CreateBaseMessageURI(const char *aURI);
nsByteArray m_inputStream;
protected:

View File

@ -192,25 +192,38 @@ nsParseNewsMessageURI(const char* uri, nsCString& messageUriWithoutKey, PRUint32
}
nsresult nsBuildNewsMessageURI(const char *baseURI, PRUint32 key, char** uri)
nsresult nsBuildNewsMessageURI(const char *baseURI, PRUint32 key, nsCString& uri)
{
if(!uri)
return NS_ERROR_NULL_POINTER;
// need to convert news://hostname/.. to news_message://hostname/..
uri.Append(baseURI);
uri.Append('#');
nsCString tailURI(baseURI);
char *keyStr = PR_smprintf("%u", key);
if(!keyStr)
return NS_ERROR_OUT_OF_MEMORY;
uri.Append(keyStr);
PR_smprintf_free(keyStr);
return NS_OK;
}
nsresult nsCreateNewsBaseMessageURI(const char *baseURI, char **baseMessageURI)
{
if(!baseMessageURI)
return NS_ERROR_NULL_POINTER;
nsCAutoString tailURI(baseURI);
// chop off mailbox:/
if (tailURI.Find(kNewsRootURI) == 0)
tailURI.Cut(0, PL_strlen(kNewsRootURI));
nsCAutoString baseURIStr(kNewsMessageRootURI);
baseURIStr += tailURI;
*baseMessageURI = baseURIStr.ToNewCString();
if(!*baseMessageURI)
return NS_ERROR_OUT_OF_MEMORY;
// chop off news:/
#if 0
if (tailURI.Find(kNewsRootURI) == 0)
tailURI.Cut(0, kNewsRootURILen);
#else
PRInt32 strOffset = tailURI.Find(":/");
if (strOffset != -1)
tailURI.Cut(0, strOffset+2);
#endif
*uri = PR_smprintf("%s%s#%d", kNewsMessageRootURI, tailURI.GetBuffer(), key);
return NS_OK;
}

View File

@ -40,8 +40,10 @@ extern nsresult
nsParseNewsMessageURI(const char* uri, nsCString& messageUriWithoutKey, PRUint32 *key);
extern nsresult
nsBuildNewsMessageURI(const char *baseURI, PRUint32 key, char** uri);
nsBuildNewsMessageURI(const char *baseURI, PRUint32 key, nsCString& uri);
extern nsresult
nsCreateNewsBaseMessageURI(const char *baseURI, char **baseMessageURI);
#endif //NS_NEWSUTILS_H

View File

@ -249,9 +249,14 @@ NS_IMETHODIMP nsNntpUrl::GetURI(char ** aURI)
nsXPIDLCString spec;
GetSpec(getter_Copies(spec));
char * uri = nsnull;
rv = nsBuildNewsMessageURI(spec, m_messageKey, &uri);
char * baseMessageURI;
nsCreateNewsBaseMessageURI(spec, &baseMessageURI);
nsCAutoString uriStr;
rv = nsBuildNewsMessageURI(baseMessageURI, m_messageKey, uriStr);
nsCRT::free(baseMessageURI);
if (NS_FAILED(rv)) return rv;
*aURI = uri;
*aURI = uriStr.ToNewCString();
return NS_OK;
}
else {