Back to index

lightning-sunbird  0.9+nobinonly
Public Member Functions | Protected Member Functions | Protected Attributes
nsImapOfflineDownloader Class Reference

#include <nsImapOfflineSync.h>

Inheritance diagram for nsImapOfflineDownloader:
Inheritance graph
[legend]
Collaboration diagram for nsImapOfflineDownloader:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 nsImapOfflineDownloader (nsIMsgWindow *window, nsIUrlListener *listener)
virtual ~nsImapOfflineDownloader ()
virtual nsresult ProcessNextOperation ()
PRInt32 GetCurrentUIDValidity ()
void SetCurrentUIDValidity (PRInt32 uidvalidity)
void SetPseudoOffline (PRBool pseudoOffline)
PRBool ProcessingStaleFolderUpdate ()
PRBool CreateOfflineFolder (nsIMsgFolder *folder)
void SetWindow (nsIMsgWindow *window)
void OnStartRunningUrl (in nsIURI url)
void OnStopRunningUrl (in nsIURI url, in nsresult aExitCode)
void OnStartCopy ()
 Notify the observer that the message has started to be copied.
void OnProgress (in PRUint32 aProgress, in PRUint32 aProgressMax)
 Notify the observer that progress as occurred for the message copy aProgress - aProgressMax -.
void SetMessageKey (in PRUint32 aKey)
 Setting newly created message key.
void GetMessageId (in nsCString aMessageId)
 Getting the file message message ID.
void OnStopCopy (in nsresult aStatus)
 Notify the observer that the message copied operation has completed.

Protected Member Functions

PRBool CreateOfflineFolders ()
PRBool DestFolderOnSameServer (nsIMsgFolder *destFolder)
nsresult AdvanceToNextServer ()
nsresult AdvanceToNextFolder ()
void AdvanceToFirstIMAPFolder ()
void DeleteAllOfflineOpsForCurrentDB ()
void ProcessFlagOperation (nsIMsgOfflineImapOperation *currentOp)
void ProcessKeywordOperation (nsIMsgOfflineImapOperation *op)
void ProcessMoveOperation (nsIMsgOfflineImapOperation *currentOp)
void ProcessCopyOperation (nsIMsgOfflineImapOperation *currentOp)
void ProcessEmptyTrash (nsIMsgOfflineImapOperation *currentOp)
void ProcessAppendMsgOperation (nsIMsgOfflineImapOperation *currentOp, nsOfflineImapOperationType opType)

Protected Attributes

nsCOMPtr< nsIMsgFolderm_currentFolder
nsCOMPtr< nsIMsgFolderm_singleFolderToUpdate
nsCOMPtr< nsIMsgWindowm_window
nsCOMPtr< nsISupportsArraym_allServers
nsCOMPtr< nsISupportsArraym_allFolders
nsCOMPtr< nsIMsgIncomingServerm_currentServer
nsCOMPtr< nsIEnumeratorm_serverEnumerator
nsCOMPtr< nsIFileSpecm_curTempFile
nsMsgKeyArray m_CurrentKeys
PRUint32 m_KeyIndex
nsCOMPtr< nsIMsgDatabasem_currentDB
nsCOMPtr< nsIUrlListenerm_listener
PRInt32 mCurrentUIDValidity
PRInt32 mCurrentPlaybackOpType
PRBool m_mailboxupdatesStarted
PRBool m_mailboxupdatesFinished
PRBool m_pseudoOffline
PRBool m_createdOfflineFolders

Detailed Description

Definition at line 105 of file nsImapOfflineSync.h.


Constructor & Destructor Documentation

Definition at line 1067 of file nsImapOfflineSync.cpp.

                                                                                                    : nsImapOfflineSync(aMsgWindow, aListener)
{
}

Definition at line 1071 of file nsImapOfflineSync.cpp.

{
}

Member Function Documentation

Definition at line 218 of file nsImapOfflineSync.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 190 of file nsImapOfflineSync.cpp.

{
  nsresult rv;
       // we always start by changing flags
  mCurrentPlaybackOpType = nsIMsgOfflineImapOperation::kFlagsChanged;
       
  if (m_currentFolder)
  {
    m_currentFolder->SetMsgDatabase(nsnull);
    m_currentFolder = nsnull;
  }

  if (!m_currentServer)
     rv = AdvanceToNextServer();
  else
    rv = m_serverEnumerator->Next();
  if (NS_FAILED(rv))
    rv = AdvanceToNextServer();

  if (NS_SUCCEEDED(rv) && m_serverEnumerator)
  {
    nsCOMPtr <nsISupports> supports;
    rv = m_serverEnumerator->CurrentItem(getter_AddRefs(supports));
    m_currentFolder = do_QueryInterface(supports);
  }
  return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 137 of file nsImapOfflineSync.cpp.

{
  nsresult rv;

  if (!m_allServers)
  {
    NS_ASSERTION(!m_currentServer, "this shouldn't be set");
    m_currentServer = nsnull;
    nsCOMPtr<nsIMsgAccountManager> accountManager = 
             do_GetService(NS_MSGACCOUNTMANAGER_CONTRACTID, &rv);
    NS_ASSERTION(accountManager && NS_SUCCEEDED(rv), "couldn't get account mgr");
    if (!accountManager || NS_FAILED(rv)) return rv;

    rv = accountManager->GetAllServers(getter_AddRefs(m_allServers));
    NS_ENSURE_SUCCESS(rv, rv);
  }
  PRUint32 serverIndex = (m_currentServer) ? m_allServers->IndexOf(m_currentServer) + 1 : 0;
  m_currentServer = nsnull;
  PRUint32 numServers; 
  m_allServers->Count(&numServers);
  nsCOMPtr <nsIMsgFolder> rootFolder;

  while (serverIndex < numServers)
  {
    nsCOMPtr <nsISupports> serverSupports = getter_AddRefs(m_allServers->ElementAt(serverIndex));
    serverIndex++;

    nsCOMPtr<nsIMsgIncomingServer> server = do_QueryInterface(serverSupports);
    nsCOMPtr <nsINntpIncomingServer> newsServer = do_QueryInterface(server);
    if (newsServer) // news servers aren't involved in offline imap
      continue;
    if (server)
    {
      m_currentServer = server;
      server->GetRootFolder(getter_AddRefs(rootFolder));
      if (rootFolder)
      {
        NS_NewISupportsArray(getter_AddRefs(m_allFolders));
        rv = rootFolder->ListDescendents(m_allFolders);
        if (NS_SUCCEEDED(rv))
          m_allFolders->Enumerate(getter_AddRefs(m_serverEnumerator));
        if (NS_SUCCEEDED(rv) && m_serverEnumerator)
        {
          rv = m_serverEnumerator->First();
          if (NS_SUCCEEDED(rv))
            break;
        }
      }
    }
  }
  return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 696 of file nsImapOfflineSync.cpp.

{
  nsCOMPtr<nsIMsgFolder> parent;
  folder->GetParent(getter_AddRefs(parent));

  nsCOMPtr <nsIMsgImapMailFolder> imapFolder = do_QueryInterface(parent);
  nsCOMPtr <nsIURI> createFolderURI;
   nsXPIDLCString onlineName;
  imapFolder->GetOnlineName(getter_Copies(onlineName));

  NS_ConvertASCIItoUCS2 folderName(onlineName);
  nsresult rv = imapFolder->PlaybackOfflineFolderCreate(folderName.get(), nsnull,  getter_AddRefs(createFolderURI));
  if (createFolderURI && NS_SUCCEEDED(rv))
  {
    nsCOMPtr <nsIMsgMailNewsUrl> mailnewsUrl = do_QueryInterface(createFolderURI);
    if (mailnewsUrl)
      mailnewsUrl->RegisterListener(this);
  }
  return NS_SUCCEEDED(rv) ? PR_TRUE : PR_FALSE;  // this is asynch, we have to return and be called again by the OfflineOpExitFunction
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRBool nsImapOfflineSync::CreateOfflineFolders ( ) [protected, inherited]

Definition at line 679 of file nsImapOfflineSync.cpp.

{
  while (m_currentFolder)
  {
    PRUint32 flags;
    m_currentFolder->GetFlags(&flags);
    PRBool offlineCreate = (flags & MSG_FOLDER_FLAG_CREATED_OFFLINE) != 0;
    if (offlineCreate)
    {
      if (CreateOfflineFolder(m_currentFolder))
        return PR_TRUE;
    }
    AdvanceToNextFolder();
  }
  return PR_FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1046 of file nsImapOfflineSync.cpp.

{
  m_KeyIndex = 0;
  nsCOMPtr <nsIMsgOfflineImapOperation> currentOp;
  m_currentDB->GetOfflineOpForKey(m_CurrentKeys[m_KeyIndex], PR_FALSE, getter_AddRefs(currentOp));
  while (currentOp)
  {
    // NS_ASSERTION(currentOp->GetOperationFlags() == 0);
    // delete any ops that have already played back
    m_currentDB->RemoveOfflineOp(currentOp);
    m_currentDB->Commit(nsMsgDBCommitType::kLargeCommit);
    currentOp = nsnull;
    
    if (++m_KeyIndex < m_CurrentKeys.GetSize())
      m_currentDB->GetOfflineOpForKey(m_CurrentKeys[m_KeyIndex], PR_FALSE, getter_AddRefs(currentOp));
  }
  // turn off MSG_FOLDER_FLAG_OFFLINEEVENTS
  if (m_currentFolder)
    m_currentFolder->ClearFlag(MSG_FOLDER_FLAG_OFFLINEEVENTS);
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRBool nsImapOfflineSync::DestFolderOnSameServer ( nsIMsgFolder destFolder) [protected, inherited]

Definition at line 576 of file nsImapOfflineSync.cpp.

{
  nsCOMPtr <nsIMsgIncomingServer> srcServer;
  nsCOMPtr <nsIMsgIncomingServer> dstServer;

  PRBool sameServer = PR_FALSE;
  if (NS_SUCCEEDED(m_currentFolder->GetServer(getter_AddRefs(srcServer))) 
    && NS_SUCCEEDED(destFolder->GetServer(getter_AddRefs(dstServer))))
    dstServer->Equals(srcServer, &sameServer);
  return sameServer;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 717 of file nsImapOfflineSync.cpp.

{
  if (m_currentFolder)
  {
    nsCOMPtr <nsIImapMailFolderSink> imapFolderSink = do_QueryInterface(m_currentFolder);
    if (imapFolderSink)
      imapFolderSink->GetUidValidity(&mCurrentUIDValidity);
  }
  return mCurrentUIDValidity; 
}

Here is the call graph for this function:

Here is the caller graph for this function:

Getting the file message message ID.

This method is taylored specifically for nsIMsgCopyService::CopyFileMessage() when saving Drafts/Templates. In order to work with imap server which doesn't support uidplus we have to use search comman to retrieve the key of newly created message. Message ID generated by the compose gurantee its uniqueness. aMessageId -

void nsIMsgCopyServiceListener::OnProgress ( in PRUint32  aProgress,
in PRUint32  aProgressMax 
) [inherited]

Notify the observer that progress as occurred for the message copy aProgress - aProgressMax -.

Notify the observer that the message has started to be copied.

This method is called only once, at the beginning of a message copyoperation.

Implemented in CopyListener.

Here is the caller graph for this function:

Notify the observer that the message copied operation has completed.

This method is called regardless of whether the the operation was successful. aStatus - indicate whether the operation was succeeded

void nsIUrlListener::OnStopRunningUrl ( in nsIURI  url,
in nsresult  aExitCode 
) [inherited]

Here is the caller graph for this function:

Definition at line 369 of file nsImapOfflineSync.cpp.

{
  nsCOMPtr <nsIMsgDBHdr> mailHdr;
  nsMsgKey msgKey;
  currentOp->GetMessageKey(&msgKey);
  nsresult rv = m_currentDB->GetMsgHdrForKey(msgKey, getter_AddRefs(mailHdr)); 
  if (NS_SUCCEEDED(rv) && mailHdr)
  {
    nsMsgKey messageOffset;
    PRUint32 messageSize;
    mailHdr->GetMessageOffset(&messageOffset);
    mailHdr->GetOfflineMessageSize(&messageSize);
    nsCOMPtr <nsIFileSpec>  tempFileSpec;
    nsSpecialSystemDirectory tmpFileSpec(nsSpecialSystemDirectory::OS_TemporaryDirectory);
    
    tmpFileSpec += "nscpmsg.txt";
    tmpFileSpec.MakeUnique();
    rv = NS_NewFileSpecWithSpec(tmpFileSpec,
      getter_AddRefs(tempFileSpec));
    if (tempFileSpec)
    {
      nsCOMPtr <nsIOutputStream> outputStream;
      rv = tempFileSpec->GetOutputStream(getter_AddRefs(outputStream));
      if (NS_SUCCEEDED(rv) && outputStream)
      {
        nsXPIDLCString moveDestination;
        currentOp->GetDestinationFolderURI(getter_Copies(moveDestination));
        nsCOMPtr<nsIRDFService> rdf(do_GetService(kRDFServiceCID, &rv));
        nsCOMPtr<nsIRDFResource> res;
        if (NS_FAILED(rv)) return ; // ### return error code.
        rv = rdf->GetResource(moveDestination, getter_AddRefs(res));
        if (NS_SUCCEEDED(rv))
        {
          nsCOMPtr<nsIMsgFolder> destFolder(do_QueryInterface(res, &rv));
          if (NS_SUCCEEDED(rv) && destFolder)
          {
            nsCOMPtr <nsIInputStream> offlineStoreInputStream;
            rv = destFolder->GetOfflineStoreInputStream(getter_AddRefs(offlineStoreInputStream));
            if (NS_SUCCEEDED(rv) && offlineStoreInputStream)
            {
              nsCOMPtr<nsISeekableStream> seekStream = do_QueryInterface(offlineStoreInputStream);
              NS_ASSERTION(seekStream, "non seekable stream - can't read from offline msg");
              if (seekStream)
              {
                rv = seekStream->Seek(PR_SEEK_SET, messageOffset);
                if (NS_SUCCEEDED(rv))
                {
                  // now, copy the dest folder offline store msg to the temp file
                  PRInt32 inputBufferSize = 10240;
                  char *inputBuffer = nsnull;
                  
                  while (!inputBuffer && (inputBufferSize >= 512))
                  {
                    inputBuffer = (char *) PR_Malloc(inputBufferSize);
                    if (!inputBuffer)
                      inputBufferSize /= 2;
                  }
                  PRInt32 bytesLeft;
                  PRUint32 bytesRead, bytesWritten;
                  bytesLeft = messageSize;
                  rv = NS_OK;
                  while (bytesLeft > 0 && NS_SUCCEEDED(rv))
                  {
                    PRInt32 bytesToRead = PR_MIN(inputBufferSize, bytesLeft);
                    rv = offlineStoreInputStream->Read(inputBuffer, bytesToRead, &bytesRead);
                    if (NS_SUCCEEDED(rv) && bytesRead > 0)
                    {
                      rv = outputStream->Write(inputBuffer, bytesRead, &bytesWritten);
                      NS_ASSERTION(bytesWritten == bytesRead, "wrote out correct number of bytes");
                    }
                    else
                      break;
                    bytesLeft -= bytesRead;
                  }
                  outputStream->Flush();
                  tempFileSpec->CloseStream();
                  if (NS_SUCCEEDED(rv))
                  {
                    m_curTempFile = tempFileSpec;
                    nsCOMPtr<nsIMsgCopyService> copyService = do_GetService(NS_MSGCOPYSERVICE_CONTRACTID);
                    if (copyService)
                      rv = copyService->CopyFileMessage(tempFileSpec, destFolder,
                      /* nsIMsgDBHdr* msgToReplace */ nsnull,
                      PR_TRUE /* isDraftOrTemplate */,
                      0, // new msg flags - are there interesting flags here?
                        this,
                        m_window);
                  }
                  else
                    tempFileSpec->Delete(PR_FALSE);
                }
                currentOp->ClearOperation(nsIMsgOfflineImapOperation::kAppendDraft);
                m_currentDB->DeleteHeader(mailHdr, nsnull, PR_TRUE, PR_TRUE);
              }
            }
            // want to close in failure case too
            tempFileSpec->CloseStream();
          }
        }
      }
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 588 of file nsImapOfflineSync.cpp.

{
  nsMsgKeyArray matchingFlagKeys;
  PRUint32 currentKeyIndex = m_KeyIndex;
  nsXPIDLCString copyDestination;
  currentOp->GetCopyDestination(0, getter_Copies(copyDestination));
  PRBool copyMatches = PR_TRUE;
  
  do { // loop for all messsages with the same destination
    if (copyMatches)
    {
      nsMsgKey curKey;
      currentOp->GetMessageKey(&curKey);
      matchingFlagKeys.Add(curKey);
      currentOp->ClearOperation(nsIMsgOfflineImapOperation::kMsgCopy);
    }
    currentOp = nsnull;
    
    if (++currentKeyIndex < m_CurrentKeys.GetSize())
    {
      nsXPIDLCString nextDestination;
      nsresult rv = m_currentDB->GetOfflineOpForKey(m_CurrentKeys[currentKeyIndex], PR_FALSE, &currentOp);
      copyMatches = PR_FALSE;
      if (NS_SUCCEEDED(rv) && currentOp)
      {
        nsOfflineImapOperationType opType; 
        currentOp->GetOperation(&opType);
        if (opType & nsIMsgOfflineImapOperation::kMsgCopy)
        {
          currentOp->GetCopyDestination(0, getter_Copies(nextDestination));
          copyMatches = nsCRT::strcmp(copyDestination, nextDestination) == 0;
        }
      }
    }
  } 
  while (currentOp);
       
  nsCAutoString uids;

  nsresult rv;

  nsCOMPtr<nsIRDFResource> res;
  nsCOMPtr<nsIRDFService> rdf(do_GetService(kRDFServiceCID, &rv));
  if (NS_FAILED(rv)) return ; // ### return error code.
  rv = rdf->GetResource(copyDestination, getter_AddRefs(res));
  if (NS_SUCCEEDED(rv))
  {
    nsCOMPtr<nsIMsgFolder> destFolder(do_QueryInterface(res, &rv));
    if (NS_SUCCEEDED(rv) && destFolder)
    {
      nsCOMPtr <nsIMsgImapMailFolder> imapFolder = do_QueryInterface(m_currentFolder);
      if (imapFolder && DestFolderOnSameServer(destFolder))
      {
        rv = imapFolder->ReplayOfflineMoveCopy(matchingFlagKeys.GetArray(), matchingFlagKeys.GetSize(), PR_FALSE, destFolder,
                       this, m_window);
      }
      else
      {
        nsCOMPtr <nsISupportsArray> messages = do_CreateInstance(NS_SUPPORTSARRAY_CONTRACTID, &rv);
        if (messages && NS_SUCCEEDED(rv))
        {
          NS_NewISupportsArray(getter_AddRefs(messages));
          for (PRUint32 keyIndex = 0; keyIndex < matchingFlagKeys.GetSize(); keyIndex++)
          {
            nsCOMPtr<nsIMsgDBHdr> mailHdr = nsnull;
            rv = m_currentFolder->GetMessageHeader(matchingFlagKeys.ElementAt(keyIndex), getter_AddRefs(mailHdr));
            if (NS_SUCCEEDED(rv) && mailHdr)
            {
              nsCOMPtr<nsISupports> iSupports;
              iSupports = do_QueryInterface(mailHdr);
              messages->AppendElement(iSupports);
            }
          }
          nsCOMPtr<nsIMsgCopyService> copyService = do_GetService(NS_MSGCOPYSERVICE_CONTRACTID, &rv);
          if (copyService)
            copyService->CopyMessages(m_currentFolder, messages, destFolder, PR_FALSE, this, m_window, PR_FALSE);
        }
      }
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsImapOfflineSync::ProcessEmptyTrash ( nsIMsgOfflineImapOperation currentOp) [protected, inherited]

Definition at line 670 of file nsImapOfflineSync.cpp.

{
  m_currentFolder->EmptyTrash(m_window, this);
  // don't need to remove the current op because emptying trash will
  // delete the database.
  m_currentDB = nsnull;     // empty trash deletes the database?
}

Here is the caller graph for this function:

Definition at line 232 of file nsImapOfflineSync.cpp.

{
  nsCOMPtr <nsIMsgOfflineImapOperation> currentOp = op;
  nsMsgKeyArray matchingFlagKeys;
  PRUint32 currentKeyIndex = m_KeyIndex;

  imapMessageFlagsType matchingFlags;
  currentOp->GetNewFlags(&matchingFlags);
  imapMessageFlagsType flagOperation;
  imapMessageFlagsType newFlags;
  PRBool flagsMatch = PR_TRUE;     
  do
  {    // loop for all messsages with the same flags
    if (flagsMatch)
    {
      nsMsgKey curKey;
      currentOp->GetMessageKey(&curKey);
      matchingFlagKeys.Add(curKey);
      currentOp->ClearOperation(nsIMsgOfflineImapOperation::kFlagsChanged);
    }
    currentOp = nsnull;
    if (++currentKeyIndex < m_CurrentKeys.GetSize())
      m_currentDB->GetOfflineOpForKey(m_CurrentKeys[currentKeyIndex], PR_FALSE,
        getter_AddRefs(currentOp));
    if (currentOp)
    {
      // init the operation in the currentOp, so we don't crunch it if&when we
      // call ClearOperation above.
      nsOfflineImapOperationType operation;
      currentOp->GetOperation(&operation);
      currentOp->GetFlagOperation(&flagOperation);
      currentOp->GetNewFlags(&newFlags);
    }
    flagsMatch = (flagOperation & nsIMsgOfflineImapOperation::kFlagsChanged)
                  && (newFlags == matchingFlags);
  } while (currentOp);
       
  if (matchingFlagKeys.GetSize() > 0)
  {
    nsCAutoString uids;
    nsImapMailFolder::AllocateUidStringFromKeys(matchingFlagKeys.GetArray(), matchingFlagKeys.GetSize(), uids);
    PRUint32 curFolderFlags;
    m_currentFolder->GetFlags(&curFolderFlags);

    if (uids.get() && (curFolderFlags & MSG_FOLDER_FLAG_IMAPBOX)) 
    {
      nsresult rv = NS_OK;
      nsCOMPtr <nsIMsgImapMailFolder> imapFolder = do_QueryInterface(m_currentFolder);
      nsCOMPtr <nsIURI> uriToSetFlags;
      if (imapFolder)
      {
        rv = imapFolder->SetImapFlags(uids.get(), matchingFlags, getter_AddRefs(uriToSetFlags));
        if (NS_SUCCEEDED(rv) && uriToSetFlags)
        {
          nsCOMPtr <nsIMsgMailNewsUrl> mailnewsUrl = do_QueryInterface(uriToSetFlags);
          if (mailnewsUrl)
            mailnewsUrl->RegisterListener(this);
        }
      }
    }
  }
  else
    ProcessNextOperation();
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 63 of file nsImapOfflineSync.h.

Definition at line 297 of file nsImapOfflineSync.cpp.

{
  nsCOMPtr <nsIMsgOfflineImapOperation> currentOp = op;
  nsMsgKeyArray matchingKeywordKeys;
  PRUint32 currentKeyIndex = m_KeyIndex;

  nsXPIDLCString keywords;
  if (mCurrentPlaybackOpType == nsIMsgOfflineImapOperation::kAddKeywords)
    currentOp->GetKeywordsToAdd(getter_Copies(keywords));
  else
    currentOp->GetKeywordsToRemove(getter_Copies(keywords));
  PRBool keywordsMatch = PR_TRUE;  
  do
  {    // loop for all messsages with the same keywords
    if (keywordsMatch)
    {
      nsMsgKey curKey;
      currentOp->GetMessageKey(&curKey);
      matchingKeywordKeys.Add(curKey);
      currentOp->ClearOperation(mCurrentPlaybackOpType);
    }
    currentOp = nsnull;
    if (++currentKeyIndex < m_CurrentKeys.GetSize())
      m_currentDB->GetOfflineOpForKey(m_CurrentKeys[currentKeyIndex], PR_FALSE,
        getter_AddRefs(currentOp));
    if (currentOp)
    {
      nsXPIDLCString curOpKeywords;
      nsOfflineImapOperationType operation;
      currentOp->GetOperation(&operation);
      if (mCurrentPlaybackOpType == nsIMsgOfflineImapOperation::kAddKeywords)
        currentOp->GetKeywordsToAdd(getter_Copies(curOpKeywords));
      else
        currentOp->GetKeywordsToRemove(getter_Copies(curOpKeywords));
      keywordsMatch = (operation & mCurrentPlaybackOpType)
                  && (curOpKeywords.Equals(keywords));
    }
  } while (currentOp);
       
  if (matchingKeywordKeys.GetSize() > 0)
  {
    PRUint32 curFolderFlags;
    m_currentFolder->GetFlags(&curFolderFlags);

    if (curFolderFlags & MSG_FOLDER_FLAG_IMAPBOX)
    {
      nsresult rv = NS_OK;
      nsCOMPtr <nsIMsgImapMailFolder> imapFolder = do_QueryInterface(m_currentFolder);
      nsCOMPtr <nsIURI> uriToStoreCustomKeywords;
      if (imapFolder)
      {
        rv = imapFolder->StoreCustomKeywords(m_window, 
                    (mCurrentPlaybackOpType == nsIMsgOfflineImapOperation::kAddKeywords) ? keywords.get() : nsnull, 
                    (mCurrentPlaybackOpType == nsIMsgOfflineImapOperation::kRemoveKeywords) ? keywords.get() : nsnull, 
                    matchingKeywordKeys.GetArray(), 
                    matchingKeywordKeys.GetSize(), getter_AddRefs(uriToStoreCustomKeywords));
        if (NS_SUCCEEDED(rv) && uriToStoreCustomKeywords)
        {
          nsCOMPtr <nsIMsgMailNewsUrl> mailnewsUrl = do_QueryInterface(uriToStoreCustomKeywords);
          if (mailnewsUrl)
            mailnewsUrl->RegisterListener(this);
        }
      }
    }
  }
  else
    ProcessNextOperation();
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 474 of file nsImapOfflineSync.cpp.

{
  nsMsgKeyArray matchingFlagKeys ;
  PRUint32 currentKeyIndex = m_KeyIndex;
  nsXPIDLCString moveDestination;
  op->GetDestinationFolderURI(getter_Copies(moveDestination));
  PRBool moveMatches = PR_TRUE;
  nsCOMPtr <nsIMsgOfflineImapOperation> currentOp = op;
  do 
  {    // loop for all messsages with the same destination
    if (moveMatches)
    {
      nsMsgKey curKey;
      currentOp->GetMessageKey(&curKey);
      matchingFlagKeys.Add(curKey);
      currentOp->ClearOperation(nsIMsgOfflineImapOperation::kMsgMoved);
    }
    currentOp = nsnull;
    
    if (++currentKeyIndex < m_CurrentKeys.GetSize())
    {
      nsXPIDLCString nextDestination;
      nsresult rv = m_currentDB->GetOfflineOpForKey(m_CurrentKeys[currentKeyIndex], PR_FALSE, getter_AddRefs(currentOp));
      moveMatches = PR_FALSE;
      if (NS_SUCCEEDED(rv) && currentOp)
      {
        nsOfflineImapOperationType opType; 
        currentOp->GetOperation(&opType);
        if (opType & nsIMsgOfflineImapOperation::kMsgMoved)
        {
          currentOp->GetDestinationFolderURI(getter_Copies(nextDestination));
          moveMatches = nsCRT::strcmp(moveDestination, nextDestination) == 0;
        }
      }
    }
  } 
  while (currentOp);
  
  nsresult rv;
  
  nsCOMPtr<nsIRDFResource> res;
  nsCOMPtr<nsIRDFService> rdf(do_GetService(kRDFServiceCID, &rv));
  if (NS_FAILED(rv)) return ; // ### return error code.
  rv = rdf->GetResource(moveDestination, getter_AddRefs(res));
  if (NS_SUCCEEDED(rv))
  {
    nsCOMPtr<nsIMsgFolder> destFolder(do_QueryInterface(res, &rv));
    if (NS_SUCCEEDED(rv) && destFolder)
    {
      nsCOMPtr <nsIMsgImapMailFolder> imapFolder = do_QueryInterface(m_currentFolder);
      if (imapFolder && DestFolderOnSameServer(destFolder))
      {
        rv = imapFolder->ReplayOfflineMoveCopy(matchingFlagKeys.GetArray(), matchingFlagKeys.GetSize(), PR_TRUE, destFolder,
          this, m_window);
      }
      else
      {
        nsCOMPtr <nsISupportsArray> messages = do_CreateInstance(NS_SUPPORTSARRAY_CONTRACTID, &rv);
        if (messages && NS_SUCCEEDED(rv))
        {
          NS_NewISupportsArray(getter_AddRefs(messages));
          for (PRUint32 keyIndex = 0; keyIndex < matchingFlagKeys.GetSize(); keyIndex++)
          {
            nsCOMPtr<nsIMsgDBHdr> mailHdr = nsnull;
            rv = m_currentFolder->GetMessageHeader(matchingFlagKeys.ElementAt(keyIndex), getter_AddRefs(mailHdr));
            if (NS_SUCCEEDED(rv) && mailHdr)
            {
              PRUint32 msgSize;
              // in case of a move, the header has already been deleted,
              // so we've really got a fake header. We need to get its flags and
              // size from the offline op to have any chance of doing the move.
              mailHdr->GetMessageSize(&msgSize);
              if (!msgSize)
              {
                imapMessageFlagsType newImapFlags;
                PRUint32 msgFlags = 0;
                op->GetMsgSize(&msgSize);
                op->GetNewFlags(&newImapFlags);
                // first three bits are the same
                msgFlags |= (newImapFlags & 0x07);
                if (newImapFlags & kImapMsgForwardedFlag)
                  msgFlags |= MSG_FLAG_FORWARDED;
                mailHdr->SetFlags(msgFlags);
                mailHdr->SetMessageSize(msgSize);
              }
              nsCOMPtr<nsISupports> iSupports;
              iSupports = do_QueryInterface(mailHdr);
              messages->AppendElement(iSupports);
            }
          }
          nsCOMPtr<nsIMsgCopyService> copyService = do_GetService(NS_MSGCOPYSERVICE_CONTRACTID, &rv);
          if (copyService)
            copyService->CopyMessages(m_currentFolder, messages, destFolder, PR_TRUE, this, m_window, PR_FALSE);
        }
      }
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Reimplemented from nsImapOfflineSync.

Definition at line 1075 of file nsImapOfflineSync.cpp.

{
  nsresult rv = NS_OK;
  if (!m_mailboxupdatesStarted)
  {
    m_mailboxupdatesStarted = PR_TRUE;
    // Update the INBOX first so the updates on the remaining
    // folders pickup the results of any filter moves.
    nsCOMPtr<nsIMsgAccountManager> accountManager = 
             do_GetService(NS_MSGACCOUNTMANAGER_CONTRACTID, &rv);
    if (NS_FAILED(rv)) return rv;
    nsCOMPtr<nsISupportsArray> servers;
  
    rv = accountManager->GetAllServers(getter_AddRefs(servers));
    if (NS_FAILED(rv)) return rv;
  }
  if (!m_mailboxupdatesFinished)
  {
    AdvanceToNextServer();
    if (m_currentServer)
    {
      nsCOMPtr <nsIMsgFolder> rootMsgFolder;
      m_currentServer->GetRootFolder(getter_AddRefs(rootMsgFolder));
      nsCOMPtr<nsIMsgFolder> inbox;
      if (rootMsgFolder)
      {
          PRUint32 numFolders;
          rootMsgFolder->GetFoldersWithFlag(MSG_FOLDER_FLAG_INBOX, 1, &numFolders, getter_AddRefs(inbox));
          if (inbox)
          {
            nsCOMPtr <nsIMsgFolder> offlineImapFolder;
            nsCOMPtr <nsIMsgImapMailFolder> imapInbox = do_QueryInterface(inbox);
            if (imapInbox)
            {
              rootMsgFolder->GetFoldersWithFlag(MSG_FOLDER_FLAG_OFFLINE, 1, &numFolders, getter_AddRefs(offlineImapFolder));
              if (!offlineImapFolder)
              {
                // no imap folders configured for offline use - check if the account is set up
                // so that we always download inbox msg bodies for offline use
                nsCOMPtr <nsIImapIncomingServer> imapServer = do_QueryInterface(m_currentServer);
                if (imapServer)
                {
                  PRBool downloadBodiesOnGetNewMail = PR_FALSE;
                  imapServer->GetDownloadBodiesOnGetNewMail(&downloadBodiesOnGetNewMail);
                  if (downloadBodiesOnGetNewMail)
                    offlineImapFolder = inbox;
                }
              }
            }
            // if this isn't an imap inbox, or we have an offline imap sub-folder, then update the inbox.
            // otherwise, it's an imap inbox for an account with no folders configured for offline use,
            // so just advance to the next server.
            if (!imapInbox || offlineImapFolder)
            {
              // here we should check if this a pop3 server/inbox, and the user doesn't want
              // to download pop3 mail for offline use.
              if (!imapInbox)
              {
              }
              rv = inbox->GetNewMessages(m_window, this);
              if (NS_SUCCEEDED(rv))
                return rv; // otherwise, fall through.
            }
          }
      }
      return ProcessNextOperation(); // recurse and do next server.
    }
    else
    {
      m_allServers = nsnull;
      m_mailboxupdatesFinished = PR_TRUE;
    }
  }
  AdvanceToNextFolder();

  while (m_currentFolder)
  {
    PRUint32 folderFlags;

    m_currentDB = nsnull;
    nsCOMPtr <nsIMsgImapMailFolder> imapFolder;
    if (m_currentFolder)
      imapFolder = do_QueryInterface(m_currentFolder);
    m_currentFolder->GetFlags(&folderFlags);
    // need to check if folder has offline events, or is configured for offline
    if (imapFolder && folderFlags & MSG_FOLDER_FLAG_OFFLINE)
    {
      rv = m_currentFolder->DownloadAllForOffline(this, m_window);
      if (NS_SUCCEEDED(rv) || rv == NS_BINDING_ABORTED)
        return rv;
      // if this fails and the user didn't cancel/stop, fall through to code that advances to next folder
    }
    AdvanceToNextFolder();
  }
  if (m_listener)
    m_listener->OnStopRunningUrl(nsnull, NS_OK);
  return rv;
}

Here is the call graph for this function:

void nsImapOfflineSync::SetCurrentUIDValidity ( PRInt32  uidvalidity) [inline, inherited]

Definition at line 60 of file nsImapOfflineSync.h.

{ mCurrentUIDValidity = uidvalidity; }

Here is the caller graph for this function:

Setting newly created message key.

This method is taylored specifically for nsIMsgCopyService::CopyFileMessage() when saveing Drafts/Templates. We need to have a way to inform the client what's the key of the newly created message. aKey -

void nsImapOfflineSync::SetPseudoOffline ( PRBool  pseudoOffline) [inline, inherited]

Definition at line 62 of file nsImapOfflineSync.h.

{m_pseudoOffline = pseudoOffline;}
void nsImapOfflineSync::SetWindow ( nsIMsgWindow window) [inherited]

Definition at line 81 of file nsImapOfflineSync.cpp.

{
  m_window = window;
}

Member Data Documentation

Definition at line 87 of file nsImapOfflineSync.h.

Definition at line 86 of file nsImapOfflineSync.h.

Definition at line 101 of file nsImapOfflineSync.h.

Definition at line 94 of file nsImapOfflineSync.h.

Definition at line 83 of file nsImapOfflineSync.h.

nsMsgKeyArray nsImapOfflineSync::m_CurrentKeys [protected, inherited]

Definition at line 92 of file nsImapOfflineSync.h.

Definition at line 88 of file nsImapOfflineSync.h.

Definition at line 90 of file nsImapOfflineSync.h.

PRUint32 nsImapOfflineSync::m_KeyIndex [protected, inherited]

Definition at line 93 of file nsImapOfflineSync.h.

Definition at line 95 of file nsImapOfflineSync.h.

Definition at line 99 of file nsImapOfflineSync.h.

Definition at line 98 of file nsImapOfflineSync.h.

Definition at line 100 of file nsImapOfflineSync.h.

Definition at line 89 of file nsImapOfflineSync.h.

Definition at line 84 of file nsImapOfflineSync.h.

Definition at line 85 of file nsImapOfflineSync.h.

Definition at line 97 of file nsImapOfflineSync.h.

Definition at line 96 of file nsImapOfflineSync.h.


The documentation for this class was generated from the following files: