From 6bf0a5cb5034a7e684dcc3500e841785237ce2dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 19:32:43 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- comm/mailnews/base/src/nsImapMoveCoalescer.cpp | 198 +++++++++++++++++++++++++ 1 file changed, 198 insertions(+) create mode 100644 comm/mailnews/base/src/nsImapMoveCoalescer.cpp (limited to 'comm/mailnews/base/src/nsImapMoveCoalescer.cpp') diff --git a/comm/mailnews/base/src/nsImapMoveCoalescer.cpp b/comm/mailnews/base/src/nsImapMoveCoalescer.cpp new file mode 100644 index 0000000000..160f204a61 --- /dev/null +++ b/comm/mailnews/base/src/nsImapMoveCoalescer.cpp @@ -0,0 +1,198 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "msgCore.h" +#include "nsImapMoveCoalescer.h" +#include "nsIImapService.h" +#include "nsIMsgCopyService.h" +#include "nsIMsgFolder.h" // TO include biffState enum. Change to bool later... +#include "nsMsgFolderFlags.h" +#include "nsIMsgHdr.h" +#include "nsIMsgImapMailFolder.h" +#include "nsThreadUtils.h" +#include "nsServiceManagerUtils.h" +#include "nsComponentManagerUtils.h" +#include "mozilla/ArrayUtils.h" + +NS_IMPL_ISUPPORTS(nsImapMoveCoalescer, nsIUrlListener) + +nsImapMoveCoalescer::nsImapMoveCoalescer(nsIMsgFolder* sourceFolder, + nsIMsgWindow* msgWindow) { + m_sourceFolder = sourceFolder; + m_msgWindow = msgWindow; + m_hasPendingMoves = false; +} + +nsImapMoveCoalescer::~nsImapMoveCoalescer() {} + +nsresult nsImapMoveCoalescer::AddMove(nsIMsgFolder* folder, nsMsgKey key) { + m_hasPendingMoves = true; + int32_t folderIndex = m_destFolders.IndexOf(folder); + nsTArray* keysToAdd = nullptr; + + if (folderIndex >= 0) + keysToAdd = &(m_sourceKeyArrays[folderIndex]); + else { + m_destFolders.AppendObject(folder); + keysToAdd = m_sourceKeyArrays.AppendElement(); + if (!keysToAdd) return NS_ERROR_OUT_OF_MEMORY; + } + + if (!keysToAdd->Contains(key)) keysToAdd->AppendElement(key); + + return NS_OK; +} + +nsresult nsImapMoveCoalescer::PlaybackMoves( + bool doNewMailNotification /* = false */) { + int32_t numFolders = m_destFolders.Count(); + // Nothing to do, so don't change the member variables. + if (numFolders == 0) return NS_OK; + + nsresult rv = NS_OK; + m_hasPendingMoves = false; + m_doNewMailNotification = doNewMailNotification; + m_outstandingMoves = 0; + + for (int32_t i = 0; i < numFolders; ++i) { + // XXX TODO + // JUNK MAIL RELATED + // is this the right place to make sure dest folder exists + // (and has proper flags?), before we start copying? + nsCOMPtr destFolder(m_destFolders[i]); + nsTArray& keysToAdd = m_sourceKeyArrays[i]; + int32_t numNewMessages = 0; + int32_t numKeysToAdd = keysToAdd.Length(); + if (numKeysToAdd == 0) continue; + + nsTArray> messages(keysToAdd.Length()); + for (uint32_t keyIndex = 0; keyIndex < keysToAdd.Length(); keyIndex++) { + nsCOMPtr mailHdr = nullptr; + rv = m_sourceFolder->GetMessageHeader(keysToAdd.ElementAt(keyIndex), + getter_AddRefs(mailHdr)); + if (NS_SUCCEEDED(rv) && mailHdr) { + messages.AppendElement(mailHdr); + bool isRead = false; + mailHdr->GetIsRead(&isRead); + if (!isRead) numNewMessages++; + } + } + uint32_t destFlags; + destFolder->GetFlags(&destFlags); + if (!(destFlags & + nsMsgFolderFlags::Junk)) // don't set has new on junk folder + { + destFolder->SetNumNewMessages(numNewMessages); + if (numNewMessages > 0) destFolder->SetHasNewMessages(true); + } + // adjust the new message count on the source folder + int32_t oldNewMessageCount = 0; + m_sourceFolder->GetNumNewMessages(false, &oldNewMessageCount); + if (oldNewMessageCount >= numKeysToAdd) + oldNewMessageCount -= numKeysToAdd; + else + oldNewMessageCount = 0; + + m_sourceFolder->SetNumNewMessages(oldNewMessageCount); + + keysToAdd.Clear(); + nsCOMPtr copySvc = + do_GetService("@mozilla.org/messenger/messagecopyservice;1"); + if (copySvc) { + nsCOMPtr listener; + if (m_doNewMailNotification) { + nsMoveCoalescerCopyListener* copyListener = + new nsMoveCoalescerCopyListener(this, destFolder); + if (copyListener) listener = copyListener; + } + rv = copySvc->CopyMessages(m_sourceFolder, messages, destFolder, true, + listener, m_msgWindow, false /*allowUndo*/); + if (NS_SUCCEEDED(rv)) m_outstandingMoves++; + } + } + return rv; +} + +NS_IMETHODIMP +nsImapMoveCoalescer::OnStartRunningUrl(nsIURI* aUrl) { + NS_ASSERTION(aUrl, "just a sanity check"); + return NS_OK; +} + +NS_IMETHODIMP +nsImapMoveCoalescer::OnStopRunningUrl(nsIURI* aUrl, nsresult aExitCode) { + m_outstandingMoves--; + if (m_doNewMailNotification && !m_outstandingMoves) { + nsCOMPtr imapFolder = + do_QueryInterface(m_sourceFolder); + if (imapFolder) imapFolder->NotifyIfNewMail(); + } + return NS_OK; +} + +nsTArray* nsImapMoveCoalescer::GetKeyBucket(uint32_t keyArrayIndex) { + NS_ASSERTION(keyArrayIndex < MOZ_ARRAY_LENGTH(m_keyBuckets), "invalid index"); + + return keyArrayIndex < mozilla::ArrayLength(m_keyBuckets) + ? &(m_keyBuckets[keyArrayIndex]) + : nullptr; +} + +NS_IMPL_ISUPPORTS(nsMoveCoalescerCopyListener, nsIMsgCopyServiceListener) + +nsMoveCoalescerCopyListener::nsMoveCoalescerCopyListener( + nsImapMoveCoalescer* coalescer, nsIMsgFolder* destFolder) { + m_destFolder = destFolder; + m_coalescer = coalescer; +} + +nsMoveCoalescerCopyListener::~nsMoveCoalescerCopyListener() {} + +NS_IMETHODIMP nsMoveCoalescerCopyListener::OnStartCopy() { + return NS_ERROR_NOT_IMPLEMENTED; +} + +/* void OnProgress (in uint32_t aProgress, in uint32_t aProgressMax); */ +NS_IMETHODIMP nsMoveCoalescerCopyListener::OnProgress(uint32_t aProgress, + uint32_t aProgressMax) { + return NS_ERROR_NOT_IMPLEMENTED; +} + +/* void SetMessageKey (in uint32_t aKey); */ +NS_IMETHODIMP nsMoveCoalescerCopyListener::SetMessageKey(uint32_t aKey) { + return NS_ERROR_NOT_IMPLEMENTED; +} + +/* void GetMessageId (in nsACString aMessageId); */ +NS_IMETHODIMP nsMoveCoalescerCopyListener::GetMessageId(nsACString& messageId) { + return NS_ERROR_NOT_IMPLEMENTED; +} + +/* void OnStopCopy (in nsresult aStatus); */ +NS_IMETHODIMP nsMoveCoalescerCopyListener::OnStopCopy(nsresult aStatus) { + nsresult rv = NS_OK; + if (NS_SUCCEEDED(aStatus)) { + // if the dest folder is imap, update it. + nsCOMPtr imapFolder = do_QueryInterface(m_destFolder); + if (imapFolder) { + uint32_t folderFlags; + m_destFolder->GetFlags(&folderFlags); + if (!(folderFlags & (nsMsgFolderFlags::Junk | nsMsgFolderFlags::Trash))) { + nsCOMPtr imapService = + do_GetService("@mozilla.org/messenger/imapservice;1", &rv); + NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr url; + rv = imapService->SelectFolder(m_destFolder, m_coalescer, nullptr, + getter_AddRefs(url)); + } + } else // give junk filters a chance to run on new msgs in destination + // local folder + { + bool filtersRun; + m_destFolder->CallFilterPlugins(nullptr, &filtersRun); + } + } + return rv; +} -- cgit v1.2.3