NS_IMETHODIMP nsMessengerBootstrap::OpenMessengerWindowWithUri(const char *windowType, const char * aFolderURI, nsMsgKey aMessageKey)
{
  bool standAloneMsgWindow = false;
  nsCAutoString chromeUrl("chrome://messenger/content/");
  if (windowType && !strcmp(windowType, "mail:messageWindow"))
  {
    chromeUrl.Append("messageWindow.xul");
    standAloneMsgWindow = true;
  }
  nsCOMPtr<nsISupportsArray> argsArray;
  nsresult rv = NS_NewISupportsArray(getter_AddRefs(argsArray));
  NS_ENSURE_SUCCESS(rv, rv);

  // create scriptable versions of our strings that we can store in our nsISupportsArray....
  if (aFolderURI)
  {
    if (standAloneMsgWindow)
    {
      nsCOMPtr <nsIMsgFolder> folder;
      rv = GetExistingFolder(nsDependentCString(aFolderURI), getter_AddRefs(folder));
      NS_ENSURE_SUCCESS(rv, rv);
      nsCAutoString msgUri;
      folder->GetBaseMessageURI(msgUri);

      nsCOMPtr<nsISupportsCString> scriptableMsgURI (do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID));
      NS_ENSURE_TRUE(scriptableMsgURI, NS_ERROR_FAILURE);
      msgUri.Append('#');
      msgUri.AppendInt(aMessageKey, 10);
      scriptableMsgURI->SetData(msgUri);
      argsArray->AppendElement(scriptableMsgURI);
      
    }
    nsCOMPtr<nsISupportsCString> scriptableFolderURI (do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID));
    NS_ENSURE_TRUE(scriptableFolderURI, NS_ERROR_FAILURE);

    scriptableFolderURI->SetData(nsDependentCString(aFolderURI));
    argsArray->AppendElement(scriptableFolderURI);

    if (!standAloneMsgWindow)
    {
      nsCOMPtr<nsISupportsPRUint32> scriptableMessageKey (do_CreateInstance(NS_SUPPORTS_PRUINT32_CONTRACTID));
      NS_ENSURE_TRUE(scriptableMessageKey, NS_ERROR_FAILURE);
      scriptableMessageKey->SetData(aMessageKey);
      argsArray->AppendElement(scriptableMessageKey);
    }
  }
  
  nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv));
  NS_ENSURE_SUCCESS(rv, rv);

  // we need to use the "mailnews.reuse_thread_window2" pref
  // to determine if we should open a new window, or use an existing one.
  nsCOMPtr<nsIDOMWindow> newWindow;
  return wwatch->OpenWindow(0, chromeUrl.get(), "_blank",
                            "chrome,all,dialog=no", argsArray,
                             getter_AddRefs(newWindow));
}
NS_IMETHODIMP nsSpamSettings::OnStopRunningUrl(nsIURI* aURL, nsresult exitCode)
{
  nsCString junkFolderURI;
  nsresult rv = GetSpamFolderURI(getter_Copies(junkFolderURI));
  NS_ENSURE_SUCCESS(rv,rv);

  if (junkFolderURI.IsEmpty())
    return NS_ERROR_UNEXPECTED;

  // when we get here, the folder should exist.
  nsCOMPtr <nsIMsgFolder> junkFolder;
  rv = GetExistingFolder(junkFolderURI, getter_AddRefs(junkFolder));
  NS_ENSURE_SUCCESS(rv,rv);
  if (!junkFolder)
    return NS_ERROR_UNEXPECTED;

  rv = junkFolder->SetFlag(nsMsgFolderFlags::Junk);
  NS_ENSURE_SUCCESS(rv,rv);
  return rv;
}
nsresult nsSpamSettings::UpdateJunkFolderState()
{
  nsresult rv;

  // if the spam folder uri changed on us, we need to unset the junk flag
  // on the old spam folder
  nsCString newJunkFolderURI;
  rv = GetSpamFolderURI(getter_Copies(newJunkFolderURI));
  NS_ENSURE_SUCCESS(rv, rv);

  if (!mCurrentJunkFolderURI.IsEmpty() && !mCurrentJunkFolderURI.Equals(newJunkFolderURI))
  {
    nsCOMPtr<nsIMsgFolder> oldJunkFolder;
    rv = GetExistingFolder(mCurrentJunkFolderURI, getter_AddRefs(oldJunkFolder));
    if (NS_SUCCEEDED(rv) && oldJunkFolder)
    {
      // remove the nsMsgFolderFlags::Junk on the old junk folder
      // XXX TODO
      // JUNK MAIL RELATED
      // (in ClearFlag?) we need to make sure that this folder
      // is not the junk folder for another account
      // the same goes for set flag.  have fun with all that.
      oldJunkFolder->ClearFlag(nsMsgFolderFlags::Junk);
    }
  }

  mCurrentJunkFolderURI = newJunkFolderURI;

  // only try to create the junk folder if we are moving junk
  // and we have a non-empty uri
  if (mMoveOnSpam && !mCurrentJunkFolderURI.IsEmpty()) {
    // as the url listener, the spam settings will set the nsMsgFolderFlags::Junk folder flag
    // on the junk mail folder, after it is created
    rv = GetOrCreateFolder(mCurrentJunkFolderURI, this);
  }

  return rv;
}
// This is the function that looks for the first folder to purge. It also
// applies retention settings to any folder that hasn't had retention settings
// applied in mMinDelayBetweenPurges minutes (default, 8 hours).
// However, if we've spent more than .5 seconds in this loop, don't
// apply any more retention settings because it might lock up the UI.
// This might starve folders later on in the hierarchy, since we always
// start at the top, but since we also apply retention settings when you
// open a folder, or when you compact all folders, I think this will do
// for now, until we have a cleanup on shutdown architecture.
nsresult nsMsgPurgeService::PerformPurge()
{
    PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("performing purge"));

    nsresult rv;

    nsCOMPtr <nsIMsgAccountManager> accountManager = do_GetService(NS_MSGACCOUNTMANAGER_CONTRACTID, &rv);
    NS_ENSURE_SUCCESS(rv,rv);
    bool keepApplyingRetentionSettings = true;

    nsCOMPtr<nsISupportsArray> allServers;
    rv = accountManager->GetAllServers(getter_AddRefs(allServers));
    if (NS_SUCCEEDED(rv) && allServers)
    {
        PRUint32 numServers;
        rv = allServers->Count(&numServers);
        PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("%d servers", numServers));
        nsCOMPtr<nsIMsgFolder> folderToPurge;
        PRIntervalTime startTime = PR_IntervalNow();
        PRInt32 purgeIntervalToUse;
        PRTime oldestPurgeTime = 0; // we're going to pick the least-recently purged folder

        // apply retention settings to folders that haven't had retention settings
        // applied in mMinDelayBetweenPurges minutes (default 8 hours)
        // Because we get last purge time from the folder cache,
        // this code won't open db's for folders until it decides it needs
        // to apply retention settings, and since nsIMsgFolder::ApplyRetentionSettings
        // will close any db's it opens, this code won't leave db's open.
        for (PRUint32 serverIndex=0; serverIndex < numServers; serverIndex++)
        {
            nsCOMPtr <nsIMsgIncomingServer> server =
                do_QueryElementAt(allServers, serverIndex, &rv);
            if (NS_SUCCEEDED(rv) && server)
            {
                if (keepApplyingRetentionSettings)
                {
                    nsCOMPtr <nsIMsgFolder> rootFolder;
                    rv = server->GetRootFolder(getter_AddRefs(rootFolder));
                    NS_ENSURE_SUCCESS(rv, rv);

                    nsCOMPtr <nsISupportsArray> childFolders = do_CreateInstance(NS_SUPPORTSARRAY_CONTRACTID, &rv);
                    NS_ENSURE_SUCCESS(rv, rv);
                    rv = rootFolder->ListDescendents(childFolders);

                    PRUint32 cnt = 0;
                    childFolders->Count(&cnt);

                    nsCOMPtr<nsISupports> supports;
                    nsCOMPtr<nsIUrlListener> urlListener;
                    nsCOMPtr<nsIMsgFolder> childFolder;

                    for (PRUint32 index = 0; index < cnt; index++)
                    {
                        childFolder = do_QueryElementAt(childFolders, index);
                        if (childFolder)
                        {
                            PRUint32 folderFlags;
                            (void) childFolder->GetFlags(&folderFlags);
                            if (folderFlags & nsMsgFolderFlags::Virtual)
                                continue;
                            PRTime curFolderLastPurgeTime = 0;
                            nsCString curFolderLastPurgeTimeString, curFolderUri;
                            rv = childFolder->GetStringProperty("LastPurgeTime", curFolderLastPurgeTimeString);
                            if (NS_FAILED(rv))
                                continue; // it is ok to fail, go on to next folder

                            if (!curFolderLastPurgeTimeString.IsEmpty())
                            {
                                PRInt64 theTime;
                                PR_ParseTimeString(curFolderLastPurgeTimeString.get(), PR_FALSE, &theTime);
                                curFolderLastPurgeTime = theTime;
                            }

                            childFolder->GetURI(curFolderUri);
                            PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("%s curFolderLastPurgeTime=%s (if blank, then never)", curFolderUri.get(), curFolderLastPurgeTimeString.get()));

                            // check if this folder is due to purge
                            // has to have been purged at least mMinDelayBetweenPurges minutes ago
                            // we don't want to purge the folders all the time - once a day is good enough
                            PRInt64 minDelayBetweenPurges(mMinDelayBetweenPurges);
                            PRInt64 microSecondsPerMinute(60000000);
                            PRTime nextPurgeTime = curFolderLastPurgeTime + (minDelayBetweenPurges * microSecondsPerMinute);
                            if (nextPurgeTime < PR_Now())
                            {
                                PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("purging %s", curFolderUri.get()));
                                childFolder->ApplyRetentionSettings();
                            }
                            PRIntervalTime elapsedTime;
                            LL_SUB(elapsedTime, PR_IntervalNow(), startTime);
                            // check if more than 500 milliseconds have elapsed in this purge process
                            if (PR_IntervalToMilliseconds(elapsedTime) > 500)
                            {
                                keepApplyingRetentionSettings = PR_FALSE;
                                break;
                            }
                        }
                    }
                }
                nsCString type;
                nsresult rv = server->GetType(type);
                NS_ENSURE_SUCCESS(rv, rv);

                nsCAutoString contractid(NS_MSGPROTOCOLINFO_CONTRACTID_PREFIX);
                contractid.Append(type);

                nsCOMPtr<nsIMsgProtocolInfo> protocolInfo =
                    do_GetService(contractid.get(), &rv);
                NS_ENSURE_SUCCESS(rv, PR_FALSE);

                nsCString realHostName;
                server->GetRealHostName(realHostName);
                PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("[%d] %s (%s)", serverIndex, realHostName.get(), type.get()));

                nsCOMPtr <nsISpamSettings> spamSettings;
                rv = server->GetSpamSettings(getter_AddRefs(spamSettings));
                NS_ENSURE_SUCCESS(rv, rv);

                PRInt32 spamLevel;
                spamSettings->GetLevel(&spamLevel);
                PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("[%d] spamLevel=%d (if 0, don't purge)", serverIndex, spamLevel));
                if (!spamLevel)
                    continue;

                // check if we are set up to purge for this server
                // if not, skip it.
                bool purgeSpam;
                spamSettings->GetPurge(&purgeSpam);

                PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("[%d] purgeSpam=%s (if false, don't purge)", serverIndex, purgeSpam ? "true" : "false"));
                if (!purgeSpam)
                    continue;

                // check if the spam folder uri is set for this server
                // if not skip it.
                nsCString junkFolderURI;
                rv = spamSettings->GetSpamFolderURI(getter_Copies(junkFolderURI));
                NS_ENSURE_SUCCESS(rv,rv);

                PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("[%d] junkFolderURI=%s (if empty, don't purge)", serverIndex, junkFolderURI.get()));
                if (junkFolderURI.IsEmpty())
                    continue;

                // if the junk folder doesn't exist
                // because the folder pane isn't built yet, for example
                // skip this account
                nsCOMPtr<nsIMsgFolder> junkFolder;
                GetExistingFolder(junkFolderURI, getter_AddRefs(junkFolder));

                PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("[%d] %s exists? %s (if doesn't exist, don't purge)", serverIndex, junkFolderURI.get(), junkFolder ? "true" : "false"));
                if (!junkFolder)
                    continue;

                PRTime curJunkFolderLastPurgeTime = 0;
                nsCString curJunkFolderLastPurgeTimeString;
                rv = junkFolder->GetStringProperty("curJunkFolderLastPurgeTime", curJunkFolderLastPurgeTimeString);
                if (NS_FAILED(rv))
                    continue; // it is ok to fail, junk folder may not exist

                if (!curJunkFolderLastPurgeTimeString.IsEmpty())
                {
                    PRInt64 theTime;
                    PR_ParseTimeString(curJunkFolderLastPurgeTimeString.get(), PR_FALSE, &theTime);
                    curJunkFolderLastPurgeTime = theTime;
                }

                PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("[%d] %s curJunkFolderLastPurgeTime=%s (if blank, then never)", serverIndex, junkFolderURI.get(), curJunkFolderLastPurgeTimeString.get()));

                // check if this account is due to purge
                // has to have been purged at least mMinDelayBetweenPurges minutes ago
                // we don't want to purge the folders all the time
                PRTime nextPurgeTime = curJunkFolderLastPurgeTime + mMinDelayBetweenPurges * 60000000 /* convert mMinDelayBetweenPurges to into microseconds */;
                if (nextPurgeTime < PR_Now())
                {
                    PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("[%d] last purge greater than min delay", serverIndex));

                    nsCOMPtr <nsIMsgIncomingServer> junkFolderServer;
                    rv = junkFolder->GetServer(getter_AddRefs(junkFolderServer));
                    NS_ENSURE_SUCCESS(rv,rv);

                    bool serverBusy = false;
                    bool serverRequiresPassword = true;
                    bool passwordPromptRequired;
                    bool canSearchMessages = false;
                    junkFolderServer->GetPasswordPromptRequired(&passwordPromptRequired);
                    junkFolderServer->GetServerBusy(&serverBusy);
                    junkFolderServer->GetServerRequiresPasswordForBiff(&serverRequiresPassword);
                    junkFolderServer->GetCanSearchMessages(&canSearchMessages);
                    // Make sure we're logged on before doing the search (assuming we need to be)
                    // and make sure the server isn't already in the middle of downloading new messages
                    // and make sure a search isn't already going on
                    PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("[%d] (search in progress? %s)", serverIndex, mSearchSession ? "true" : "false"));
                    PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("[%d] (server busy? %s)", serverIndex, serverBusy ? "true" : "false"));
                    PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("[%d] (serverRequiresPassword? %s)", serverIndex, serverRequiresPassword ? "true" : "false"));
                    PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("[%d] (passwordPromptRequired? %s)", serverIndex, passwordPromptRequired ? "true" : "false"));
                    if (canSearchMessages && !mSearchSession && !serverBusy && (!serverRequiresPassword || !passwordPromptRequired))
                    {
                        PRInt32 purgeInterval;
                        spamSettings->GetPurgeInterval(&purgeInterval);

                        if ((oldestPurgeTime == 0) || (curJunkFolderLastPurgeTime < oldestPurgeTime))
                        {
                            PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("[%d] purging! searching for messages older than %d days", serverIndex, purgeInterval));
                            oldestPurgeTime = curJunkFolderLastPurgeTime;
                            purgeIntervalToUse = purgeInterval;
                            folderToPurge = junkFolder;
                            // if we've never purged this folder, do it...
                            if (curJunkFolderLastPurgeTime == 0)
                                break;
                        }
                    }
                    else {
                        NS_ASSERTION(canSearchMessages, "unexpected, you should be able to search");
                        PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("[%d] not a good time for this server, try again later", serverIndex));
                    }
                }
                else {
                    PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("[%d] last purge too recent", serverIndex));
                }
            }
        }
        if (folderToPurge)
            rv = SearchFolderToPurge(folderToPurge, purgeIntervalToUse);
    }

    // set up timer to check accounts again
    SetupNextPurge();
    return rv;
}
Exemple #5
0
void nsImapOfflineSync::ProcessCopyOperation(nsIMsgOfflineImapOperation *currentOp)
{
  nsTArray<nsMsgKey> matchingFlagKeys;
  PRUint32 currentKeyIndex = m_KeyIndex;
  nsCString 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.AppendElement(curKey);
      currentOp->SetPlayingBack(PR_TRUE);
      m_currentOpsToClear.AppendObject(currentOp);
    }
    currentOp = nsnull;

    if (++currentKeyIndex < m_CurrentKeys.Length())
    {
      nsCString 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 = copyDestination.Equals(nextDestination);
        }
      }
    }
  } 
  while (currentOp);

  nsCAutoString uids;
  nsCOMPtr<nsIMsgFolder> destFolder;
  GetExistingFolder(copyDestination, getter_AddRefs(destFolder));
  // if the dest folder doesn't really exist, these operations are
  // going to fail, so clear them out and move on.
  if (!destFolder)
  {
    NS_ERROR("trying to playing back copy to non-existent folder");
    ClearCurrentOps();
    ProcessNextOperation();
    return;
  }
  nsresult rv;
  nsCOMPtr<nsIMsgImapMailFolder> imapFolder = do_QueryInterface(m_currentFolder);
  if (imapFolder && DestFolderOnSameServer(destFolder))
  {
    rv = imapFolder->ReplayOfflineMoveCopy(matchingFlagKeys.Elements(), matchingFlagKeys.Length(), PR_FALSE, destFolder,
                   this, m_window);
  }
  else
  {
    nsCOMPtr<nsIMutableArray> messages(do_CreateInstance(NS_ARRAY_CONTRACTID, &rv));
    if (messages && NS_SUCCEEDED(rv))
    {
      for (PRUint32 keyIndex = 0; keyIndex < matchingFlagKeys.Length(); keyIndex++)
      {
        nsCOMPtr<nsIMsgDBHdr> mailHdr = nsnull;
        rv = m_currentFolder->GetMessageHeader(matchingFlagKeys.ElementAt(keyIndex), getter_AddRefs(mailHdr));
        if (NS_SUCCEEDED(rv) && mailHdr)
        {
          messages->AppendElement(mailHdr, PR_FALSE);
        }
      }
      nsCOMPtr<nsIMsgCopyService> copyService = do_GetService(NS_MSGCOPYSERVICE_CONTRACTID, &rv);
      if (copyService)
        copyService->CopyMessages(m_currentFolder, messages, destFolder, PR_FALSE, this, m_window, PR_FALSE);
    }
  }
}
Exemple #6
0
void nsImapOfflineSync::ProcessMoveOperation(nsIMsgOfflineImapOperation *op)
{
  nsTArray<nsMsgKey> matchingFlagKeys;
  PRUint32 currentKeyIndex = m_KeyIndex;
  nsCString 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.AppendElement(curKey);
      currentOp->SetPlayingBack(PR_TRUE);
      m_currentOpsToClear.AppendObject(currentOp);
    }
    currentOp = nsnull;
    
    if (++currentKeyIndex < m_CurrentKeys.Length())
    {
      nsCString 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 = moveDestination.Equals(nextDestination);
        }
      }
    }
  } 
  while (currentOp);
  
  nsCOMPtr<nsIMsgFolder> destFolder;
  GetExistingFolder(moveDestination, getter_AddRefs(destFolder));
  // if the dest folder doesn't really exist, these operations are
  // going to fail, so clear them out and move on.
  if (!destFolder)
  {
    NS_ERROR("trying to playing back move to non-existent folder");
    ClearCurrentOps();
    ProcessNextOperation();
    return;
  }
  nsCOMPtr<nsIMsgImapMailFolder> imapFolder = do_QueryInterface(m_currentFolder);
  if (imapFolder && DestFolderOnSameServer(destFolder))
  {
    imapFolder->ReplayOfflineMoveCopy(matchingFlagKeys.Elements(), matchingFlagKeys.Length(), PR_TRUE, destFolder,
      this, m_window);
  }
  else
  {
    nsresult rv;
    nsCOMPtr<nsIMutableArray> messages(do_CreateInstance(NS_ARRAY_CONTRACTID, &rv));
    if (NS_SUCCEEDED(rv))
    {
      for (PRUint32 keyIndex = 0; keyIndex < matchingFlagKeys.Length(); 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 |= nsMsgMessageFlags::Forwarded;
            mailHdr->SetFlags(msgFlags);
            mailHdr->SetMessageSize(msgSize);
          }
          messages->AppendElement(mailHdr, PR_FALSE);
        }
      }
      nsCOMPtr<nsIMsgCopyService> copyService = do_GetService(NS_MSGCOPYSERVICE_CONTRACTID, &rv);
      if (copyService)
        copyService->CopyMessages(m_currentFolder, messages, destFolder, PR_TRUE, this, m_window, PR_FALSE);
    }
  }
}