Bug 505456 - Make imap folders with offline store not fetch from IMAP when copying to local folders. r=mkmelin
authorGene Smith <gds@chartertn.net>
Sat, 08 Feb 2020 12:54:30 +0200
changeset 37260 9185bf0f28e29d56ad0c2fc5cb167b2ef000669d
parent 37259 7dc97f6d28a347bee552760e270dbdb254b03e7a
child 37261 a5f5ab445b92956503cfa3dcc3651a6c82e6fbca
push id2552
push userclokep@gmail.com
push dateMon, 10 Feb 2020 21:24:16 +0000
treeherdercomm-beta@f95a6f4408a3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmkmelin
bugs505456
Bug 505456 - Make imap folders with offline store not fetch from IMAP when copying to local folders. r=mkmelin Now the copy or move is sourced from the offline store if all selected messages are in offline store.
mailnews/local/src/nsLocalMailFolder.cpp
--- a/mailnews/local/src/nsLocalMailFolder.cpp
+++ b/mailnews/local/src/nsLocalMailFolder.cpp
@@ -1317,43 +1317,51 @@ nsMsgLocalMailFolder::CopyMessages(nsIMs
     return OnCopyCompleted(srcSupport, false);
   }
 
   UpdateTimestamps(allowUndo);
   nsCString protocolType;
   rv = srcFolder->GetURI(protocolType);
   protocolType.SetLength(protocolType.FindChar(':'));
 
-  bool needOfflineBody =
+  // If we're offline and the source folder is imap or news, to do the
+  // copy the message bodies MUST reside in offline storage.
+  bool needOfflineBodies =
       (WeAreOffline() && (MsgLowerCaseEqualsLiteral(protocolType, "imap") ||
                           MsgLowerCaseEqualsLiteral(protocolType, "news")));
   int64_t totalMsgSize = 0;
   uint32_t numMessages = 0;
+  bool allMsgsHaveOfflineStore = true;
   messages->GetLength(&numMessages);
   for (uint32_t i = 0; i < numMessages; i++) {
     nsCOMPtr<nsIMsgDBHdr> message(do_QueryElementAt(messages, i, &rv));
     if (NS_SUCCEEDED(rv) && message) {
       nsMsgKey key;
       uint32_t msgSize;
       message->GetMessageSize(&msgSize);
 
       /* 200 is a per-message overhead to account for any extra data added
          to the message.
       */
       totalMsgSize += msgSize + 200;
 
-      if (needOfflineBody) {
-        bool hasMsgOffline = false;
-        message->GetMessageKey(&key);
-        srcFolder->HasMsgOffline(key, &hasMsgOffline);
-        if (!hasMsgOffline) {
-          if (isMove) srcFolder->NotifyFolderEvent(kDeleteOrMoveMsgFailed);
-          ThrowAlertMsg("cantMoveMsgWOBodyOffline", msgWindow);
-          return OnCopyCompleted(srcSupport, false);
-        }
+      // Check if each source folder message has offline storage regardless
+      // of whether we're online or offline.
+      message->GetMessageKey(&key);
+      bool hasMsgOffline = false;
+      srcFolder->HasMsgOffline(key, &hasMsgOffline);
+      allMsgsHaveOfflineStore = allMsgsHaveOfflineStore && hasMsgOffline;
+
+      // If we're offline and not all messages are in offline storage, the copy
+      // or move can't occur and a notification for the user to download the
+      // messages is posted.
+      if (needOfflineBodies && !hasMsgOffline) {
+        if (isMove) srcFolder->NotifyFolderEvent(kDeleteOrMoveMsgFailed);
+        ThrowAlertMsg("cantMoveMsgWOBodyOffline", msgWindow);
+        return OnCopyCompleted(srcSupport, false);
       }
     }
   }
 
   if (!CheckIfSpaceForCopy(msgWindow, srcFolder, srcSupport, isMove,
                            totalMsgSize))
     return NS_OK;
 
@@ -1461,27 +1469,33 @@ nsMsgLocalMailFolder::CopyMessages(nsIMs
         else
           msgTxn->SetTransactionType(nsIMessenger::eMoveMsg);
       } else
         msgTxn->SetTransactionType(nsIMessenger::eCopyMsg);
       msgTxn.swap(mCopyState->m_undoMsgTxn);
     }
   }
 
-  if (numMsgs > 1 &&
-      ((MsgLowerCaseEqualsLiteral(protocolType, "imap") && !WeAreOffline()) ||
-       MsgLowerCaseEqualsLiteral(protocolType, "mailbox"))) {
+  if (numMsgs > 1 && ((MsgLowerCaseEqualsLiteral(protocolType, "imap") &&
+                       !allMsgsHaveOfflineStore) ||
+                      MsgLowerCaseEqualsLiteral(protocolType, "mailbox"))) {
+    // For an imap source folder with more than one message to be copied that
+    // are not all in offline storage, this fetches all the messages from the
+    // imap server to do the copy. When source folder is "mailbox", this is not
+    // a concern since source messages are in local storage.
     mCopyState->m_copyingMultipleMessages = true;
     rv = CopyMessagesTo(mCopyState->m_messages, keyArray, msgWindow, this,
                         isMove);
     if (NS_FAILED(rv)) {
       NS_ERROR("copy message failed");
       (void)OnCopyCompleted(srcSupport, false);
     }
   } else {
+    // This obtains the source messages from local/offline storage to do the
+    // copy. Note: CopyMessageTo() actually handles one or more messages.
     nsCOMPtr<nsISupports> msgSupport =
         do_QueryElementAt(mCopyState->m_messages, 0);
     if (msgSupport) {
       rv = CopyMessageTo(msgSupport, this, msgWindow, isMove);
       if (NS_FAILED(rv)) {
         NS_ASSERTION(false, "copy message failed");
         (void)OnCopyCompleted(srcSupport, false);
       }