示例#1
0
// this is used for Send without UI
nsresult nsMapiHook::BlindSendMail (unsigned long aSession, nsIMsgCompFields * aCompFields)
{
  nsresult rv = NS_OK ;

  if (!IsBlindSendAllowed())
    return NS_ERROR_FAILURE;

  /** create nsIMsgComposeParams obj and other fields to populate it **/

  nsCOMPtr<nsIDOMWindow>  hiddenWindow;
  // get parent window
  nsCOMPtr<nsIAppShellService> appService = do_GetService( "@mozilla.org/appshell/appShellService;1", &rv);
  if (NS_FAILED(rv)|| (!appService) ) return rv ;

  rv = appService->GetHiddenDOMWindow(getter_AddRefs(hiddenWindow));
  if ( NS_FAILED(rv) ) return rv ;
  // smtp password and Logged in used IdKey from MapiConfig (session obj)
  nsMAPIConfiguration * pMapiConfig = nsMAPIConfiguration::GetMAPIConfiguration() ;
  if (!pMapiConfig) return NS_ERROR_FAILURE ;  // get the singelton obj
  PRUnichar * password = pMapiConfig->GetPassword(aSession) ;
  // password
  nsCAutoString smtpPassword;
  LossyCopyUTF16toASCII(password, smtpPassword);

  // Id key
  nsCString MsgIdKey;
  pMapiConfig->GetIdKey(aSession, MsgIdKey);

  // get the MsgIdentity for the above key using AccountManager
  nsCOMPtr <nsIMsgAccountManager> accountManager = do_GetService (NS_MSGACCOUNTMANAGER_CONTRACTID) ;
  if (NS_FAILED(rv) || (!accountManager) ) return rv ;

  nsCOMPtr <nsIMsgIdentity> pMsgId ;
  rv = accountManager->GetIdentity (MsgIdKey, getter_AddRefs(pMsgId)) ;
  if (NS_FAILED(rv) ) return rv ;

  // create a send listener to get back the send status
  nsCOMPtr <nsIMsgSendListener> sendListener ;
  rv = nsMAPISendListener::CreateMAPISendListener(getter_AddRefs(sendListener)) ;
  if (NS_FAILED(rv) || (!sendListener) ) return rv;

  // create the compose params object
  nsCOMPtr<nsIMsgComposeParams> pMsgComposeParams (do_CreateInstance(NS_MSGCOMPOSEPARAMS_CONTRACTID, &rv));
  if (NS_FAILED(rv) || (!pMsgComposeParams) ) return rv ;

  // populate the compose params
  bool forcePlainText;
  aCompFields->GetForcePlainText(&forcePlainText);
  pMsgComposeParams->SetType(nsIMsgCompType::New);
  pMsgComposeParams->SetFormat(forcePlainText ? nsIMsgCompFormat::PlainText : nsIMsgCompFormat::HTML);
  pMsgComposeParams->SetIdentity(pMsgId);
  pMsgComposeParams->SetComposeFields(aCompFields);
  pMsgComposeParams->SetSendListener(sendListener) ;
  pMsgComposeParams->SetSmtpPassword(smtpPassword.get());

  // create the nsIMsgCompose object to send the object
  nsCOMPtr<nsIMsgCompose> pMsgCompose (do_CreateInstance(NS_MSGCOMPOSE_CONTRACTID, &rv));
  if (NS_FAILED(rv) || (!pMsgCompose) ) return rv ;

  /** initialize nsIMsgCompose, Send the message, wait for send completion response **/

  rv = pMsgCompose->Initialize(pMsgComposeParams, hiddenWindow, nsnull);
  if (NS_FAILED(rv)) return rv ;

  // If we're in offline mode, we'll need to queue it for later. No point in trying to send it.
  return pMsgCompose->SendMsg(WeAreOffline() ? nsIMsgSend::nsMsgQueueForLater : nsIMsgSend::nsMsgDeliverNow,
			      pMsgId, nsnull, nsnull, nsnull);
  if (NS_FAILED(rv)) return rv ;

  // assign to interface pointer from nsCOMPtr to facilitate typecast below
  nsIMsgSendListener * pSendListener = sendListener ;

  // we need to wait here to make sure that we return only after send is completed
  // so we will have a event loop here which will process the events till the Send IsDone.
  nsCOMPtr<nsIThread> thread(do_GetCurrentThread());
  while ( !((nsMAPISendListener *) pSendListener)->IsDone() )
  {
    PR_CEnterMonitor(pSendListener);
    PR_CWait(pSendListener, PR_MicrosecondsToInterval(1000UL));
    PR_CExitMonitor(pSendListener);
    NS_ProcessPendingEvents(thread);
  }

  return rv ;
}
示例#2
0
NS_IMETHODIMP nsImapOfflineTxn::RedoTransaction(void)
{
  nsresult rv;
  
  nsCOMPtr<nsIMsgFolder> srcFolder = do_QueryReferent(m_srcFolder, &rv);
  if (NS_FAILED(rv) || !srcFolder) 
    return rv;
  nsCOMPtr <nsIMsgOfflineImapOperation> op;
  nsCOMPtr <nsIDBFolderInfo> folderInfo;
  nsCOMPtr <nsIMsgDatabase> srcDB;
  nsCOMPtr <nsIMsgDatabase> destDB;
  rv = srcFolder->GetDBFolderInfoAndDB(getter_AddRefs(folderInfo), getter_AddRefs(srcDB));
  NS_ENSURE_SUCCESS(rv, rv);
  nsMsgKey hdrKey = nsMsgKey_None;

  switch (m_opType)
  {
  case nsIMsgOfflineImapOperation::kMsgMoved:
  case nsIMsgOfflineImapOperation::kMsgCopy:
    for (int32_t i = 0; i < m_srcHdrs.Count(); i++)
    {
      nsMsgKey hdrKey;
      m_srcHdrs[i]->GetMessageKey(&hdrKey);
      rv = srcDB->GetOfflineOpForKey(hdrKey, false, getter_AddRefs(op));
      if (NS_SUCCEEDED(rv) && op)
      {
        nsCOMPtr<nsIMsgFolder> dstFolder = do_QueryReferent(m_dstFolder, &rv);
        if (dstFolder)
        {
          nsCString folderURI;
          dstFolder->GetURI(folderURI);

          if (m_opType == nsIMsgOfflineImapOperation::kMsgMoved)
            op->SetDestinationFolderURI(folderURI.get()); // offline move
          if (m_opType == nsIMsgOfflineImapOperation::kMsgCopy)
          {
            op->SetOperation(nsIMsgOfflineImapOperation::kMsgMoved);
            op->AddMessageCopyOperation(folderURI.get()); // offline copy
          }
          dstFolder->SummaryChanged();
        }
      }
      else if (!WeAreOffline())
      {
        // couldn't find offline op - it must have been played back already
        // so we should redo the transaction online.
        return nsImapMoveCopyMsgTxn::RedoTransaction();
      }
    }
    break;
  case nsIMsgOfflineImapOperation::kAddedHeader:
    {
      nsCOMPtr<nsIMsgFolder> dstFolder = do_QueryReferent(m_dstFolder, &rv);
      rv = srcFolder->GetDBFolderInfoAndDB(getter_AddRefs(folderInfo), getter_AddRefs(destDB));
      NS_ENSURE_SUCCESS(rv, rv);
      for (int32_t i = 0; i < m_srcHdrs.Count(); i++)
      {
        nsCOMPtr<nsIMsgDBHdr> restoreHdr;
        nsMsgKey msgKey;
        m_srcHdrs[i]->GetMessageKey(&msgKey);
        destDB->CopyHdrFromExistingHdr (msgKey, m_srcHdrs[i], true, getter_AddRefs(restoreHdr));
        rv = destDB->GetOfflineOpForKey(msgKey, true, getter_AddRefs(op));
        if (NS_SUCCEEDED(rv) && op)
        {
          nsCString folderURI;
          srcFolder->GetURI(folderURI);
          op->SetSourceFolderURI(folderURI.get());
        }
      }
      dstFolder->SummaryChanged();
      destDB->Close(true);
    }
    break;
  case nsIMsgOfflineImapOperation::kDeletedMsg:
    for (int32_t i = 0; i < m_srcHdrs.Count(); i++)
    {
      nsMsgKey msgKey;
      m_srcHdrs[i]->GetMessageKey(&msgKey);
      srcDB->DeleteMessage(msgKey, nullptr, true);
    }
    break;
  case nsIMsgOfflineImapOperation::kMsgMarkedDeleted:
    for (int32_t i = 0; i < m_srcHdrs.Count(); i++)
    {
      nsMsgKey msgKey;
      m_srcHdrs[i]->GetMessageKey(&msgKey);
      srcDB->MarkImapDeleted(msgKey, true, nullptr);
    }
    break;
  case nsIMsgOfflineImapOperation::kFlagsChanged:
    for (int32_t i = 0; i < m_srcHdrs.Count(); i++)
    {
      nsMsgKey msgKey;
      m_srcHdrs[i]->GetMessageKey(&msgKey);
      rv = srcDB->GetOfflineOpForKey(msgKey, true, getter_AddRefs(op));
      if (NS_SUCCEEDED(rv) && op)
      {
        imapMessageFlagsType newMsgFlags;
        op->GetNewFlags(&newMsgFlags);
        if (m_addFlags)
          op->SetFlagOperation(newMsgFlags | m_flags);
        else
          op->SetFlagOperation(newMsgFlags & ~m_flags);
      }
    }
    break;
  default:
    break;
  }
  srcDB->Close(true);
  srcDB = nullptr;
  srcFolder->SummaryChanged();
  return NS_OK;
}
示例#3
0
// Open the database and find the key for the offline operation that we want to
// undo, then remove it from the database, we also hold on to this
// data for a redo operation.
NS_IMETHODIMP nsImapOfflineTxn::UndoTransaction(void)
{
  nsresult rv;
  
  nsCOMPtr<nsIMsgFolder> srcFolder = do_QueryReferent(m_srcFolder, &rv);
  if (NS_FAILED(rv) || !srcFolder) 
    return rv;
  nsCOMPtr <nsIMsgOfflineImapOperation> op;
  nsCOMPtr <nsIDBFolderInfo> folderInfo;
  nsCOMPtr <nsIMsgDatabase> srcDB;
  nsCOMPtr <nsIMsgDatabase> destDB;

  nsMsgKey hdrKey = nsMsgKey_None;

  if (m_header)
    m_header->GetMessageKey(&hdrKey);

  rv = srcFolder->GetDBFolderInfoAndDB(getter_AddRefs(folderInfo), getter_AddRefs(srcDB));
  NS_ENSURE_SUCCESS(rv, rv);

  switch (m_opType)
  {
    case nsIMsgOfflineImapOperation::kMsgMoved:
    case nsIMsgOfflineImapOperation::kMsgCopy:
    case nsIMsgOfflineImapOperation::kAddedHeader:
    case nsIMsgOfflineImapOperation::kFlagsChanged:
    {
      rv = srcDB->GetOfflineOpForKey(hdrKey, PR_FALSE, getter_AddRefs(op));
      PRBool offlineOpPlayedBack = PR_TRUE;
      if (NS_SUCCEEDED(rv) && op)
      {
        op->GetPlayingBack(&offlineOpPlayedBack);
        srcDB->RemoveOfflineOp(op);
        op = nsnull;
      }
      if (!WeAreOffline() && offlineOpPlayedBack)
      {
        // couldn't find offline op - it must have been played back already
        // so we should undo the transaction online.
        return nsImapMoveCopyMsgTxn::UndoTransaction();
      }

      if (m_header && (m_opType == nsIMsgOfflineImapOperation::kAddedHeader))
      {
        nsCOMPtr <nsIMsgDBHdr> mailHdr;
        nsMsgKey msgKey;
        m_header->GetMessageKey(&msgKey);
        rv = srcDB->GetMsgHdrForKey(msgKey, getter_AddRefs(mailHdr));
        if (mailHdr)
          srcDB->DeleteHeader(mailHdr, nsnull, PR_TRUE, PR_FALSE);
      }
      break;
    }
    case nsIMsgOfflineImapOperation::kDeletedMsg:
      {
        nsMsgKey msgKey;
        m_header->GetMessageKey(&msgKey);
        nsCOMPtr<nsIMsgDBHdr> undeletedHdr;
        m_srcHdrs->QueryElementAt(0, NS_GET_IID(nsIMsgDBHdr), getter_AddRefs(undeletedHdr));
        if (undeletedHdr)
        {
          nsCOMPtr<nsIMsgDBHdr> newHdr;

          srcDB->CopyHdrFromExistingHdr (msgKey, undeletedHdr, PR_TRUE, getter_AddRefs(newHdr));
        }
        srcDB->Close(PR_TRUE);
        srcFolder->SummaryChanged();
      }
      break;
    case nsIMsgOfflineImapOperation::kMsgMarkedDeleted:
      srcDB->MarkImapDeleted(hdrKey, PR_FALSE, nsnull);
      break;
    default:
      break;
  }
  srcDB->Close(PR_TRUE);
  srcFolder->SummaryChanged();
  return NS_OK;
}
示例#4
0
// Open the database and find the key for the offline operation that we want to
// undo, then remove it from the database, we also hold on to this
// data for a redo operation.
NS_IMETHODIMP nsImapOfflineTxn::UndoTransaction(void)
{
  nsresult rv;

  nsCOMPtr<nsIMsgFolder> srcFolder = do_QueryReferent(m_srcFolder, &rv);
  if (NS_FAILED(rv) || !srcFolder) 
    return rv;
  nsCOMPtr <nsIMsgOfflineImapOperation> op;
  nsCOMPtr <nsIDBFolderInfo> folderInfo;
  nsCOMPtr <nsIMsgDatabase> srcDB;
  nsCOMPtr <nsIMsgDatabase> destDB;

  rv = srcFolder->GetDBFolderInfoAndDB(getter_AddRefs(folderInfo), getter_AddRefs(srcDB));
  NS_ENSURE_SUCCESS(rv, rv);

  switch (m_opType)
  {
    case nsIMsgOfflineImapOperation::kMsgMoved:
    case nsIMsgOfflineImapOperation::kMsgCopy:
    case nsIMsgOfflineImapOperation::kAddedHeader:
    case nsIMsgOfflineImapOperation::kFlagsChanged:
    case nsIMsgOfflineImapOperation::kDeletedMsg:
    {
      if (m_srcHdrs.Count() == 0)
      {
        NS_ASSERTION(false, "No msg header to apply undo.");
        break;
      }
      nsCOMPtr<nsIMsgDBHdr> firstHdr = m_srcHdrs[0];
      nsMsgKey hdrKey;
      firstHdr->GetMessageKey(&hdrKey);
      rv = srcDB->GetOfflineOpForKey(hdrKey, false, getter_AddRefs(op));
      bool offlineOpPlayedBack = true;
      if (NS_SUCCEEDED(rv) && op)
      {
        op->GetPlayingBack(&offlineOpPlayedBack);
        srcDB->RemoveOfflineOp(op);
        op = nullptr;
      }
      if (!WeAreOffline() && offlineOpPlayedBack)
      {
        // couldn't find offline op - it must have been played back already
        // so we should undo the transaction online.
        return nsImapMoveCopyMsgTxn::UndoTransaction();
      }

      if (!firstHdr)
        break;
      nsMsgKey msgKey;
      if (m_opType == nsIMsgOfflineImapOperation::kAddedHeader)
      {
        for (int32_t i = 0; i < m_srcHdrs.Count(); i++)
        {
          m_srcHdrs[i]->GetMessageKey(&msgKey);
          nsCOMPtr<nsIMsgDBHdr> mailHdr;
          rv = srcDB->GetMsgHdrForKey(msgKey, getter_AddRefs(mailHdr));
          if (mailHdr)
            srcDB->DeleteHeader(mailHdr, nullptr, false, false);
        }
        srcDB->Commit(true);
      }
      else if (m_opType == nsIMsgOfflineImapOperation::kDeletedMsg)
      {
        for (int32_t i = 0; i < m_srcHdrs.Count(); i++)
        {
          nsCOMPtr<nsIMsgDBHdr> undeletedHdr = m_srcHdrs[i];
          m_srcHdrs[i]->GetMessageKey(&msgKey);
          if (undeletedHdr)
          {
            nsCOMPtr<nsIMsgDBHdr> newHdr;
            srcDB->CopyHdrFromExistingHdr (msgKey, undeletedHdr, true, getter_AddRefs(newHdr));
          }
        }
        srcDB->Close(true);
        srcFolder->SummaryChanged();
      }
      break;
    }
    case nsIMsgOfflineImapOperation::kMsgMarkedDeleted:
      {
        nsMsgKey msgKey;
        for (int32_t i = 0; i < m_srcHdrs.Count(); i++)
        {
          m_srcHdrs[i]->GetMessageKey(&msgKey);
          srcDB->MarkImapDeleted(msgKey, false, nullptr);
        }
      }
      break;
    default:
      break;
  }
  srcDB->Close(true);
  srcFolder->SummaryChanged();
  return NS_OK;
}
示例#5
0
nsresult
nsMsgSendLater::InternalSendMessages(bool aUserInitiated,
                                     nsIMsgIdentity *aIdentity)
{
  if (WeAreOffline())
    return NS_MSG_ERROR_OFFLINE;

  // Protect against being called whilst we're already sending.
  if (mSendingMessages)
  {
    NS_ERROR("nsMsgSendLater is already sending messages\n");
    return NS_ERROR_FAILURE;
  }

  nsresult rv;

  // XXX This code should be set up for multiple unsent folders, however we
  // don't support that at the moment, so for now just assume one folder.
  if (!mMessageFolder)
  {
    rv = GetUnsentMessagesFolder(nullptr,
                                 getter_AddRefs(mMessageFolder));
    NS_ENSURE_SUCCESS(rv, rv);
  }
  nsCOMPtr<nsIMsgDatabase> unsentDB;
  // Remember these in case we need to reparse the db.
  mUserInitiated = aUserInitiated;
  mIdentity = aIdentity;
  rv = ReparseDBIfNeeded(this);
  NS_ENSURE_SUCCESS(rv, rv);
  mIdentity = nullptr; // don't hold onto the identity since we're a service.

  nsCOMPtr<nsISimpleEnumerator> enumerator;
  rv = mMessageFolder->GetMessages(getter_AddRefs(enumerator));
  NS_ENSURE_SUCCESS(rv, rv);

  // copy all the elements in the enumerator into our isupports array....

  nsCOMPtr<nsISupports> currentItem;
  nsCOMPtr<nsIMsgDBHdr> messageHeader;
  bool hasMoreElements = false;
  while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMoreElements)) && hasMoreElements)
  {
    rv = enumerator->GetNext(getter_AddRefs(currentItem));
    if (NS_SUCCEEDED(rv))
    {
      messageHeader = do_QueryInterface(currentItem, &rv);
      if (NS_SUCCEEDED(rv))
      {
        if (aUserInitiated)
          // If the user initiated the send, add all messages
          mMessagesToSend.AppendObject(messageHeader);
        else
        {
          // Else just send those that are NOT marked as Queued.
          uint32_t flags;
          rv = messageHeader->GetFlags(&flags);
          if (NS_SUCCEEDED(rv) && !(flags & nsMsgMessageFlags::Queued))
            mMessagesToSend.AppendObject(messageHeader);
        }  
      }
    }
  }

  // Now get an enumerator for our array.
  rv = NS_NewArrayEnumerator(getter_AddRefs(mEnumerator), mMessagesToSend);
  NS_ENSURE_SUCCESS(rv, rv);

  // We're now sending messages so its time to signal that and reset our counts.
  mSendingMessages = true;
  mTotalSentSuccessfully = 0;
  mTotalSendCount = 0;

  // Notify the listeners that we are starting a send.
  NotifyListenersOnStartSending(mMessagesToSend.Count());

  return StartNextMailFileSend(NS_OK);
}