diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
commit | 6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch) | |
tree | a68f146d7fa01f0134297619fbe7e33db084e0aa /comm/mailnews/db/msgdb/src/nsMsgOfflineImapOperation.cpp | |
parent | Initial commit. (diff) | |
download | thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.tar.xz thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.zip |
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'comm/mailnews/db/msgdb/src/nsMsgOfflineImapOperation.cpp')
-rw-r--r-- | comm/mailnews/db/msgdb/src/nsMsgOfflineImapOperation.cpp | 385 |
1 files changed, 385 insertions, 0 deletions
diff --git a/comm/mailnews/db/msgdb/src/nsMsgOfflineImapOperation.cpp b/comm/mailnews/db/msgdb/src/nsMsgOfflineImapOperation.cpp new file mode 100644 index 0000000000..96410654d8 --- /dev/null +++ b/comm/mailnews/db/msgdb/src/nsMsgOfflineImapOperation.cpp @@ -0,0 +1,385 @@ +/* -*- 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 "nsMsgOfflineImapOperation.h" +#include "nsMsgUtils.h" +#include "mozilla/Logging.h" + +using namespace mozilla; + +LazyLogModule IMAPOffline("IMAPOffline"); + +/* Implementation file */ +NS_IMPL_ISUPPORTS(nsMsgOfflineImapOperation, nsIMsgOfflineImapOperation) + +// property names for offine imap operation fields. +#define PROP_OPERATION "op" +#define PROP_OPERATION_FLAGS "opFlags" +#define PROP_NEW_FLAGS "newFlags" +#define PROP_MESSAGE_KEY "msgKey" +#define PROP_SRC_MESSAGE_KEY "srcMsgKey" +#define PROP_SRC_FOLDER_URI "srcFolderURI" +#define PROP_MOVE_DEST_FOLDER_URI "moveDest" +#define PROP_NUM_COPY_DESTS "numCopyDests" +#define PROP_COPY_DESTS \ + "copyDests" // how to delimit these? Or should we do the "dest1","dest2" etc + // trick? But then we'd need to shuffle them around since we + // delete off the front first. +#define PROP_KEYWORD_ADD "addedKeywords" +#define PROP_KEYWORD_REMOVE "removedKeywords" +#define PROP_MSG_SIZE "msgSize" +#define PROP_PLAYINGBACK "inPlayback" + +nsMsgOfflineImapOperation::nsMsgOfflineImapOperation(nsMsgDatabase* db, + nsIMdbRow* row) { + NS_ASSERTION(db, "can't have null db"); + NS_ASSERTION(row, "can't have null row"); + m_operation = 0; + m_operationFlags = 0; + m_messageKey = nsMsgKey_None; + m_sourceMessageKey = nsMsgKey_None; + m_mdb = db; + NS_ADDREF(m_mdb); + m_mdbRow = row; + m_newFlags = 0; + m_mdb->GetUint32Property(m_mdbRow, PROP_OPERATION, (uint32_t*)&m_operation, + 0); + m_mdb->GetUint32Property(m_mdbRow, PROP_MESSAGE_KEY, &m_messageKey, 0); + m_mdb->GetUint32Property(m_mdbRow, PROP_OPERATION_FLAGS, &m_operationFlags, + 0); + m_mdb->GetUint32Property(m_mdbRow, PROP_NEW_FLAGS, (uint32_t*)&m_newFlags, 0); +} + +nsMsgOfflineImapOperation::~nsMsgOfflineImapOperation() { + // clear the row first, in case we're holding the last reference + // to the db. + m_mdbRow = nullptr; + NS_IF_RELEASE(m_mdb); +} + +/* attribute nsOfflineImapOperationType operation; */ +NS_IMETHODIMP nsMsgOfflineImapOperation::GetOperation( + nsOfflineImapOperationType* aOperation) { + NS_ENSURE_ARG(aOperation); + *aOperation = m_operation; + return NS_OK; +} + +NS_IMETHODIMP nsMsgOfflineImapOperation::SetOperation( + nsOfflineImapOperationType aOperation) { + if (MOZ_LOG_TEST(IMAPOffline, LogLevel::Info)) + MOZ_LOG(IMAPOffline, LogLevel::Info, + ("msg id %x setOperation was %x add %x", m_messageKey, m_operation, + aOperation)); + + m_operation |= aOperation; + return m_mdb->SetUint32Property(m_mdbRow, PROP_OPERATION, m_operation); +} + +/* void clearOperation (in nsOfflineImapOperationType operation); */ +NS_IMETHODIMP nsMsgOfflineImapOperation::ClearOperation( + nsOfflineImapOperationType aOperation) { + if (MOZ_LOG_TEST(IMAPOffline, LogLevel::Info)) + MOZ_LOG(IMAPOffline, LogLevel::Info, + ("msg id %x clearOperation was %x clear %x", m_messageKey, + m_operation, aOperation)); + m_operation &= ~aOperation; + switch (aOperation) { + case kMsgMoved: + case kAppendTemplate: + case kAppendDraft: + m_moveDestination.Truncate(); + break; + case kMsgCopy: + m_copyDestinations.RemoveElementAt(0); + break; + } + return m_mdb->SetUint32Property(m_mdbRow, PROP_OPERATION, m_operation); +} + +/* attribute nsMsgKey messageKey; */ +NS_IMETHODIMP nsMsgOfflineImapOperation::GetMessageKey(nsMsgKey* aMessageKey) { + NS_ENSURE_ARG(aMessageKey); + *aMessageKey = m_messageKey; + return NS_OK; +} + +NS_IMETHODIMP nsMsgOfflineImapOperation::SetMessageKey(nsMsgKey aMessageKey) { + m_messageKey = aMessageKey; + return m_mdb->SetUint32Property(m_mdbRow, PROP_MESSAGE_KEY, m_messageKey); +} + +/* attribute nsMsgKey srcMessageKey; */ +NS_IMETHODIMP nsMsgOfflineImapOperation::GetSrcMessageKey( + nsMsgKey* aMessageKey) { + NS_ENSURE_ARG(aMessageKey); + return m_mdb->GetUint32Property(m_mdbRow, PROP_SRC_MESSAGE_KEY, aMessageKey, + nsMsgKey_None); +} + +NS_IMETHODIMP nsMsgOfflineImapOperation::SetSrcMessageKey( + nsMsgKey aMessageKey) { + m_messageKey = aMessageKey; + return m_mdb->SetUint32Property(m_mdbRow, PROP_SRC_MESSAGE_KEY, m_messageKey); +} + +/* attribute imapMessageFlagsType flagOperation; */ +NS_IMETHODIMP nsMsgOfflineImapOperation::GetFlagOperation( + imapMessageFlagsType* aFlagOperation) { + NS_ENSURE_ARG(aFlagOperation); + *aFlagOperation = m_operationFlags; + return NS_OK; +} + +NS_IMETHODIMP nsMsgOfflineImapOperation::SetFlagOperation( + imapMessageFlagsType aFlagOperation) { + if (MOZ_LOG_TEST(IMAPOffline, LogLevel::Info)) + MOZ_LOG(IMAPOffline, LogLevel::Info, + ("msg id %x setFlagOperation was %x add %x", m_messageKey, + m_operationFlags, aFlagOperation)); + SetOperation(kFlagsChanged); + nsresult rv = SetNewFlags(aFlagOperation); + NS_ENSURE_SUCCESS(rv, rv); + m_operationFlags |= aFlagOperation; + return m_mdb->SetUint32Property(m_mdbRow, PROP_OPERATION_FLAGS, + m_operationFlags); +} + +/* attribute imapMessageFlagsType flagOperation; */ +NS_IMETHODIMP nsMsgOfflineImapOperation::GetNewFlags( + imapMessageFlagsType* aNewFlags) { + NS_ENSURE_ARG(aNewFlags); + uint32_t flags; + nsresult rv = m_mdb->GetUint32Property(m_mdbRow, PROP_NEW_FLAGS, &flags, 0); + *aNewFlags = m_newFlags = (imapMessageFlagsType)flags; + return rv; +} + +NS_IMETHODIMP nsMsgOfflineImapOperation::SetNewFlags( + imapMessageFlagsType aNewFlags) { + if (MOZ_LOG_TEST(IMAPOffline, LogLevel::Info) && m_newFlags != aNewFlags) + MOZ_LOG(IMAPOffline, LogLevel::Info, + ("msg id %x SetNewFlags was %x to %x", m_messageKey, m_newFlags, + aNewFlags)); + m_newFlags = aNewFlags; + return m_mdb->SetUint32Property(m_mdbRow, PROP_NEW_FLAGS, m_newFlags); +} + +/* attribute string destinationFolderURI; */ +NS_IMETHODIMP nsMsgOfflineImapOperation::GetDestinationFolderURI( + nsACString& aDestinationFolderURI) { + (void)m_mdb->GetProperty(m_mdbRow, PROP_MOVE_DEST_FOLDER_URI, + getter_Copies(m_moveDestination)); + aDestinationFolderURI = m_moveDestination; + return NS_OK; +} + +NS_IMETHODIMP nsMsgOfflineImapOperation::SetDestinationFolderURI( + const nsACString& aDestinationFolderURI) { + if (MOZ_LOG_TEST(IMAPOffline, LogLevel::Info)) + MOZ_LOG(IMAPOffline, LogLevel::Info, + ("msg id %x SetDestinationFolderURI to %s", m_messageKey, + PromiseFlatCString(aDestinationFolderURI).get())); + m_moveDestination = aDestinationFolderURI; + return m_mdb->SetProperty(m_mdbRow, PROP_MOVE_DEST_FOLDER_URI, + PromiseFlatCString(aDestinationFolderURI).get()); +} + +/* attribute string sourceFolderURI; */ +NS_IMETHODIMP nsMsgOfflineImapOperation::GetSourceFolderURI( + nsACString& aSourceFolderURI) { + nsresult rv = m_mdb->GetProperty(m_mdbRow, PROP_SRC_FOLDER_URI, + getter_Copies(m_sourceFolder)); + aSourceFolderURI = m_sourceFolder; + return rv; +} + +NS_IMETHODIMP nsMsgOfflineImapOperation::SetSourceFolderURI( + const nsACString& aSourceFolderURI) { + m_sourceFolder = aSourceFolderURI; + SetOperation(kMoveResult); + + return m_mdb->SetProperty(m_mdbRow, PROP_SRC_FOLDER_URI, + PromiseFlatCString(aSourceFolderURI).get()); +} + +/* attribute string keyword; */ +NS_IMETHODIMP nsMsgOfflineImapOperation::GetKeywordsToAdd(char** aKeywords) { + NS_ENSURE_ARG(aKeywords); + nsresult rv = m_mdb->GetProperty(m_mdbRow, PROP_KEYWORD_ADD, + getter_Copies(m_keywordsToAdd)); + *aKeywords = ToNewCString(m_keywordsToAdd); + return rv; +} + +NS_IMETHODIMP nsMsgOfflineImapOperation::AddKeywordToAdd(const char* aKeyword) { + SetOperation(kAddKeywords); + return AddKeyword(aKeyword, m_keywordsToAdd, PROP_KEYWORD_ADD, + m_keywordsToRemove, PROP_KEYWORD_REMOVE); +} + +NS_IMETHODIMP nsMsgOfflineImapOperation::GetKeywordsToRemove(char** aKeywords) { + NS_ENSURE_ARG(aKeywords); + nsresult rv = m_mdb->GetProperty(m_mdbRow, PROP_KEYWORD_REMOVE, + getter_Copies(m_keywordsToRemove)); + *aKeywords = ToNewCString(m_keywordsToRemove); + return rv; +} + +nsresult nsMsgOfflineImapOperation::AddKeyword(const char* aKeyword, + nsCString& addList, + const char* addProp, + nsCString& removeList, + const char* removeProp) { + int32_t startOffset, keywordLength; + if (!MsgFindKeyword(nsDependentCString(aKeyword), addList, &startOffset, + &keywordLength)) { + if (!addList.IsEmpty()) addList.Append(' '); + addList.Append(aKeyword); + } + // if the keyword we're removing was in the list of keywords to add, + // cut it from that list. + if (MsgFindKeyword(nsDependentCString(aKeyword), removeList, &startOffset, + &keywordLength)) { + removeList.Cut(startOffset, keywordLength); + m_mdb->SetProperty(m_mdbRow, removeProp, removeList.get()); + } + return m_mdb->SetProperty(m_mdbRow, addProp, addList.get()); +} + +NS_IMETHODIMP nsMsgOfflineImapOperation::AddKeywordToRemove( + const char* aKeyword) { + SetOperation(kRemoveKeywords); + return AddKeyword(aKeyword, m_keywordsToRemove, PROP_KEYWORD_REMOVE, + m_keywordsToAdd, PROP_KEYWORD_ADD); +} + +NS_IMETHODIMP nsMsgOfflineImapOperation::AddMessageCopyOperation( + const nsACString& destinationBox) { + SetOperation(kMsgCopy); + nsresult rv = GetCopiesFromDB(); + NS_ENSURE_SUCCESS(rv, rv); + m_copyDestinations.AppendElement(destinationBox); + return SetCopiesToDB(); +} + +// we write out the folders as one string, separated by 0x1. +#define FOLDER_SEP_CHAR '\001' + +nsresult nsMsgOfflineImapOperation::GetCopiesFromDB() { + nsCString copyDests; + m_copyDestinations.Clear(); + nsresult rv = + m_mdb->GetProperty(m_mdbRow, PROP_COPY_DESTS, getter_Copies(copyDests)); + // use 0x1 as the delimiter between folder names since it's not a legal + // character + if (NS_SUCCEEDED(rv) && !copyDests.IsEmpty()) { + int32_t curCopyDestStart = 0; + int32_t nextCopyDestPos = 0; + + while (nextCopyDestPos != -1) { + nsCString curDest; + nextCopyDestPos = copyDests.FindChar(FOLDER_SEP_CHAR, curCopyDestStart); + if (nextCopyDestPos > 0) + curDest = Substring(copyDests, curCopyDestStart, + nextCopyDestPos - curCopyDestStart); + else + curDest = Substring(copyDests, curCopyDestStart, + copyDests.Length() - curCopyDestStart); + curCopyDestStart = nextCopyDestPos + 1; + m_copyDestinations.AppendElement(curDest); + } + } + return rv; +} + +nsresult nsMsgOfflineImapOperation::SetCopiesToDB() { + nsAutoCString copyDests; + + // use 0x1 as the delimiter between folders + for (uint32_t i = 0; i < m_copyDestinations.Length(); i++) { + if (i > 0) copyDests.Append(FOLDER_SEP_CHAR); + copyDests.Append(m_copyDestinations.ElementAt(i)); + } + return m_mdb->SetProperty(m_mdbRow, PROP_COPY_DESTS, copyDests.get()); +} + +/* attribute long numberOfCopies; */ +NS_IMETHODIMP nsMsgOfflineImapOperation::GetNumberOfCopies( + int32_t* aNumberOfCopies) { + NS_ENSURE_ARG(aNumberOfCopies); + nsresult rv = GetCopiesFromDB(); + NS_ENSURE_SUCCESS(rv, rv); + *aNumberOfCopies = m_copyDestinations.Length(); + return NS_OK; +} + +/* string getCopyDestination (in long copyIndex); */ +NS_IMETHODIMP nsMsgOfflineImapOperation::GetCopyDestination(int32_t copyIndex, + char** retval) { + NS_ENSURE_ARG(retval); + nsresult rv = GetCopiesFromDB(); + NS_ENSURE_SUCCESS(rv, rv); + if (copyIndex >= (int32_t)m_copyDestinations.Length()) + return NS_ERROR_ILLEGAL_VALUE; + *retval = ToNewCString(m_copyDestinations.ElementAt(copyIndex)); + return (*retval) ? NS_OK : NS_ERROR_OUT_OF_MEMORY; +} + +/* attribute unsigned log msgSize; */ +NS_IMETHODIMP nsMsgOfflineImapOperation::GetMsgSize(uint32_t* aMsgSize) { + NS_ENSURE_ARG(aMsgSize); + return m_mdb->GetUint32Property(m_mdbRow, PROP_MSG_SIZE, aMsgSize, 0); +} + +NS_IMETHODIMP nsMsgOfflineImapOperation::SetMsgSize(uint32_t aMsgSize) { + return m_mdb->SetUint32Property(m_mdbRow, PROP_MSG_SIZE, aMsgSize); +} + +NS_IMETHODIMP nsMsgOfflineImapOperation::SetPlayingBack(bool aPlayingBack) { + return m_mdb->SetBooleanProperty(m_mdbRow, PROP_PLAYINGBACK, aPlayingBack); +} + +NS_IMETHODIMP nsMsgOfflineImapOperation::GetPlayingBack(bool* aPlayingBack) { + NS_ENSURE_ARG(aPlayingBack); + return m_mdb->GetBooleanProperty(m_mdbRow, PROP_PLAYINGBACK, aPlayingBack); +} + +void nsMsgOfflineImapOperation::Log() { + if (!MOZ_LOG_TEST(IMAPOffline, LogLevel::Info)) return; + // const long kMoveResult = 0x8; + // const long kAppendDraft = 0x10; + // const long kAddedHeader = 0x20; + // const long kDeletedMsg = 0x40; + // const long kMsgMarkedDeleted = 0x80; + // const long kAppendTemplate = 0x100; + // const long kDeleteAllMsgs = 0x200; + if (m_operation & nsIMsgOfflineImapOperation::kFlagsChanged) + MOZ_LOG(IMAPOffline, LogLevel::Info, + ("msg id %x changeFlag:%x", m_messageKey, m_newFlags)); + if (m_operation & nsIMsgOfflineImapOperation::kMsgMoved) { + nsCString moveDestFolder; + GetDestinationFolderURI(moveDestFolder); + MOZ_LOG(IMAPOffline, LogLevel::Info, + ("msg id %x moveTo:%s", m_messageKey, moveDestFolder.get())); + } + if (m_operation & nsIMsgOfflineImapOperation::kMsgCopy) { + nsCString copyDests; + m_mdb->GetProperty(m_mdbRow, PROP_COPY_DESTS, getter_Copies(copyDests)); + MOZ_LOG(IMAPOffline, LogLevel::Info, + ("msg id %x moveTo:%s", m_messageKey, copyDests.get())); + } + if (m_operation & nsIMsgOfflineImapOperation::kAppendDraft) + MOZ_LOG(IMAPOffline, LogLevel::Info, + ("msg id %x append draft", m_messageKey)); + if (m_operation & nsIMsgOfflineImapOperation::kAddKeywords) + MOZ_LOG(IMAPOffline, LogLevel::Info, + ("msg id %x add keyword:%s", m_messageKey, m_keywordsToAdd.get())); + if (m_operation & nsIMsgOfflineImapOperation::kRemoveKeywords) + MOZ_LOG(IMAPOffline, LogLevel::Info, + ("msg id %x remove keyword:%s", m_messageKey, + m_keywordsToRemove.get())); +} |