use append uid returned by imap server when possible,
bug 646225, r=neil
--- a/mailnews/imap/src/nsImapMailFolder.cpp
+++ b/mailnews/imap/src/nsImapMailFolder.cpp
@@ -3297,20 +3297,18 @@ NS_IMETHODIMP nsImapMailFolder::BeginCop
}
NS_IMETHODIMP nsImapMailFolder::CopyDataToOutputStreamForAppend(nsIInputStream *aIStream,
PRInt32 aLength, nsIOutputStream *outputStream)
{
PRUint32 readCount;
PRUint32 writeCount;
if (!m_copyState)
- {
- nsImapMailCopyState* copyState = new nsImapMailCopyState();
- m_copyState = do_QueryInterface(copyState);
- }
+ m_copyState = new nsImapMailCopyState();
+
if ( aLength + m_copyState->m_leftOver > m_copyState->m_dataBufferSize )
{
m_copyState->m_dataBuffer = (char *) PR_REALLOC(m_copyState->m_dataBuffer, aLength + m_copyState->m_leftOver+ 1);
NS_ENSURE_TRUE(m_copyState->m_dataBuffer, NS_ERROR_OUT_OF_MEMORY);
m_copyState->m_dataBufferSize = aLength + m_copyState->m_leftOver;
}
char *start, *end;
@@ -5737,17 +5735,20 @@ nsImapMailFolder::SetAppendMsgUid(nsMsgK
if (mailCopyState->m_undoMsgTxn) // CopyMessages()
{
nsRefPtr<nsImapMoveCopyMsgTxn> msgTxn;
msgTxn = mailCopyState->m_undoMsgTxn;
msgTxn->AddDstKey(aKey);
}
else if (mailCopyState->m_listener) // CopyFileMessage();
// Draft/Template goes here
+ {
+ mailCopyState->m_appendUID = aKey;
mailCopyState->m_listener->SetMessageKey(aKey);
+ }
}
return NS_OK;
}
NS_IMETHODIMP
nsImapMailFolder::GetMessageId(nsIImapUrl * aUrl,
nsACString &messageId)
{
@@ -8120,17 +8121,17 @@ nsImapMailFolder::CopyStreamMessage(nsIM
return rv;
}
nsImapMailCopyState::nsImapMailCopyState() :
m_isMove(PR_FALSE), m_selectedState(PR_FALSE),
m_isCrossServerOp(PR_FALSE), m_curIndex(0),
m_totalCount(0), m_streamCopy(PR_FALSE), m_dataBuffer(nsnull),
m_dataBufferSize(0), m_leftOver(0), m_allowUndo(PR_FALSE),
- m_eatLF(PR_FALSE), m_newMsgFlags(0)
+ m_eatLF(PR_FALSE), m_newMsgFlags(0), m_appendUID(nsMsgKey_None)
{
}
nsImapMailCopyState::~nsImapMailCopyState()
{
PR_Free(m_dataBuffer);
if (m_msgService && m_message)
{
@@ -8159,18 +8160,17 @@ nsImapMailFolder::InitCopyState(nsISuppo
nsIMsgCopyServiceListener* listener,
nsIMsgWindow *msgWindow,
PRBool allowUndo)
{
NS_ENSURE_ARG_POINTER(srcSupport);
NS_ENSURE_TRUE(!m_copyState, NS_ERROR_FAILURE);
nsresult rv;
- nsImapMailCopyState* copyState = new nsImapMailCopyState();
- m_copyState = do_QueryInterface(copyState);
+ m_copyState = new nsImapMailCopyState();
NS_ENSURE_TRUE(m_copyState,NS_ERROR_OUT_OF_MEMORY);
m_copyState->m_isCrossServerOp = acrossServers;
m_copyState->m_srcSupport = do_QueryInterface(srcSupport, &rv);
NS_ENSURE_SUCCESS(rv, rv);
m_copyState->m_messages = messages;
if (messages)
@@ -8220,29 +8220,29 @@ nsImapMailFolder::InitCopyState(nsISuppo
m_copyState->m_selectedState = selectedState;
m_copyState->m_msgWindow = msgWindow;
if (listener)
m_copyState->m_listener = do_QueryInterface(listener, &rv);
return rv;
}
nsresult
-nsImapMailFolder::CopyFileToOfflineStore(nsILocalFile *srcFile)
+nsImapMailFolder::CopyFileToOfflineStore(nsILocalFile *srcFile, nsMsgKey msgKey)
{
nsCOMPtr<nsIMsgDatabase> db;
nsresult rv = GetMsgDatabase(getter_AddRefs(db));
if (mDatabase)
{
- nsMsgKey fakeKey;
- mDatabase->GetNextFakeOfflineMsgKey(&fakeKey);
+ if (msgKey == nsMsgKey_None)
+ mDatabase->GetNextFakeOfflineMsgKey(&msgKey);
nsCOMPtr<nsIMutableArray> messages(do_CreateInstance(NS_ARRAY_CONTRACTID));
nsCOMPtr<nsIMsgOfflineImapOperation> op;
- rv = mDatabase->GetOfflineOpForKey(fakeKey, PR_TRUE, getter_AddRefs(op));
+ rv = mDatabase->GetOfflineOpForKey(msgKey, PR_TRUE, getter_AddRefs(op));
if (NS_SUCCEEDED(rv) && op)
{
nsCString destFolderUri;
GetURI(destFolderUri);
op->SetOperation(nsIMsgOfflineImapOperation::kMoveResult);
op->SetDestinationFolderURI(destFolderUri.get());
nsCOMPtr<nsIOutputStream> offlineStore;
rv = GetOfflineStoreOutputStream(getter_AddRefs(offlineStore));
@@ -8273,17 +8273,17 @@ nsImapMailFolder::CopyFileToOfflineStore
nsMsgLineStreamBuffer *inputStreamBuffer =
new nsMsgLineStreamBuffer(inputBufferSize, PR_TRUE, PR_FALSE);
PRInt64 fileSize;
srcFile->GetFileSize(&fileSize);
PRUint32 bytesWritten;
rv = NS_OK;
msgParser->SetState(nsIMsgParseMailMsgState::ParseHeadersState);
// set the env pos to fake key so the msg hdr will have that for a key
- msgParser->SetEnvelopePos(fakeKey);
+ msgParser->SetEnvelopePos(msgKey);
PRBool needMoreData = PR_FALSE;
char * newLine = nsnull;
PRUint32 numBytesInLine = 0;
const char *envelope = "From "CRLF;
offlineStore->Write(envelope, strlen(envelope), &bytesWritten);
fileSize += bytesWritten;
do
{
@@ -8333,17 +8333,17 @@ nsresult
nsImapMailFolder::OnCopyCompleted(nsISupports *srcSupport, nsresult rv)
{
// if it's a file, and the copy succeeded, then fcc the offline
// store, and add a kMoveResult offline op.
if (NS_SUCCEEDED(rv) && m_copyState)
{
nsCOMPtr<nsILocalFile> srcFile(do_QueryInterface(srcSupport));
if (srcFile && (mFlags & nsMsgFolderFlags::Offline) && !WeAreOffline())
- (void) CopyFileToOfflineStore(srcFile);
+ (void) CopyFileToOfflineStore(srcFile, m_copyState->m_appendUID);
}
m_copyState = nsnull;
nsresult result;
nsCOMPtr<nsIMsgCopyService> copyService = do_GetService(NS_MSGCOPYSERVICE_CONTRACTID, &result);
NS_ENSURE_SUCCESS(result, result);
return copyService->NotifyCompletion(srcSupport, this, rv);
}
--- a/mailnews/imap/src/nsImapMailFolder.h
+++ b/mailnews/imap/src/nsImapMailFolder.h
@@ -109,16 +109,19 @@ public:
char *m_dataBuffer; // temporary buffer for this copy operation
nsCOMPtr<nsIOutputStream> m_msgFileStream; // temporary file (processed mail)
PRUint32 m_dataBufferSize;
PRUint32 m_leftOver;
PRBool m_allowUndo;
PRBool m_eatLF;
PRBool m_newMsgFlags; // only used if there's no m_message
nsCString m_newMsgKeywords; // ditto
+ // If the server supports UIDPLUS, this is the UID for the append,
+ // if we're doing an append.
+ nsMsgKey m_appendUID;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsImapMailCopyState, NS_IMAPMAILCOPYSTATE_IID)
// ACLs for this folder.
// Generally, we will try to always query this class when performing
// an operation on the folder.
// If the server doesn't support ACLs, none of this data will be filled in.
@@ -372,17 +375,17 @@ protected:
PRUint16 userFlags, nsCString& keywords);
nsresult NotifyMessageFlagsFromHdr(nsIMsgDBHdr *dbHdr, nsMsgKey msgKey, PRUint32 flags);
nsresult SetupHeaderParseStream(PRUint32 size, const nsACString& content_type, nsIMailboxSpec *boxSpec);
nsresult ParseAdoptedHeaderLine(const char *messageLine, PRUint32 msgKey);
nsresult NormalEndHeaderParseStream(nsIImapProtocol *aProtocol, nsIImapUrl *imapUrl);
void EndOfflineDownload();
- nsresult CopyFileToOfflineStore(nsILocalFile *srcFile);
+ nsresult CopyFileToOfflineStore(nsILocalFile *srcFile, nsMsgKey msgKey);
nsresult MarkMessagesImapDeleted(nsTArray<nsMsgKey> *keyArray, PRBool deleted, nsIMsgDatabase *db);
// Notifies imap autosync that it should update this folder when it
// gets a chance.
void NotifyHasPendingMsgs();
void UpdatePendingCounts();
void SetIMAPDeletedFlag(nsIMsgDatabase *mailDB, const nsTArray<nsMsgKey> &msgids, PRBool markDeleted);
@@ -482,17 +485,17 @@ protected:
PRInt32 m_nextMessageByteLength;
nsCOMPtr<nsIThread> m_thread;
nsCOMPtr<nsIUrlListener> m_urlListener;
PRBool m_urlRunning;
// undo move/copy transaction support
nsRefPtr<nsMsgTxn> m_pendingUndoTxn;
- nsCOMPtr<nsImapMailCopyState> m_copyState;
+ nsRefPtr<nsImapMailCopyState> m_copyState;
char m_hierarchyDelimiter;
PRInt32 m_boxFlags;
nsCString m_onlineFolderName;
nsCString m_ownerUserName; // username of the "other user," as in
// "Other Users' Mailboxes"
nsCString m_adminUrl; // url to run to set admin privileges for this folder
nsIMAPNamespace *m_namespace;