Back to index

lightning-sunbird  0.9+nobinonly
Public Member Functions | Public Attributes | Private Member Functions | Private Attributes | Friends
nsMsgCompose Class Reference

#include <nsMsgCompose.h>

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

List of all members.

Public Member Functions

 nsMsgCompose ()
virtual ~nsMsgCompose ()
void Initialize (in nsIDOMWindowInternal aWindow, in nsIMsgComposeParams aParams)
void SetDocumentCharset (in string charset)
void RegisterStateListener (in nsIMsgComposeStateListener stateListener)
void UnregisterStateListener (in nsIMsgComposeStateListener stateListener)
void SendMsg (in MSG_DeliverMode deliverMode, in nsIMsgIdentity identity, in string accountKey, in nsIMsgWindow aMsgWindow, in nsIMsgProgress progress)
void CloseWindow (in boolean reclycleIt)
void abort ()
void quoteMessage (in string msgURI)
AUTF8String AttachmentPrettyName (in string url, in string charset)
unsigned long CheckAndPopulateRecipients (in boolean populateMailList, in boolean returnNonHTMLRecipients, out wstring nonHTMLRecipients)
long bodyConvertible ()
void SetSignature (in nsIMsgIdentity identity)
boolean checkCharsetConversion (in nsIMsgIdentity identity, out string fallbackCharset)
void initEditor (in nsIEditor editor, in nsIDOMWindow contentWindow)
 Init the editor THIS USED TO BE [noscript] Now, this is called after editor is created, which is triggered by loading startup url from JS.
void clearEditor ()
void setCiteReference (in nsString citeReference)
void processSignature (in nsIMsgIdentity identity, in boolean aQuoted, inout nsString aMsgBody)
void processReplyFlags ()
void rememberQueuedDisposition ()
void convertAndLoadComposeWindow (in nsStringRef aPrefix, in nsStringRef aBuf, in nsStringRef aSignature, in boolean aQuoted, in boolean aHTMLEditor)
void notifyStateListeners (in TStateListenerNotification aNotificationType, in nsresult aResult)
nsIMsgSendListener getExternalSendListener ()
void buildBodyMessageAndSignature ()
void buildQuotedMessageAndSignature ()
void getQuotingToFollow (out boolean quotingToFollow)

Public Attributes

readonly attribute nsIMsgSend messageSend
readonly attribute nsIEditor editor
readonly attribute
nsIDOMWindowInternal 
domWindow
readonly attribute nsIMsgCompFields compFields
readonly attribute boolean composeHTML
attribute MSG_ComposeType type
readonly attribute long wrapLength
attribute boolean bodyModified
attribute string savedFolderURI
readonly attribute nsIMsgProgress progress
attribute
nsIMsgComposeRecyclingListener 
recyclingListener
attribute boolean recycledWindow
readonly attribute string originalMsgURI
attribute boolean deleteDraft
attribute boolean insertingQuotedContent

Private Member Functions

nsresult QuoteOriginalMessage (const char *originalMsgURI, PRInt32 what)
nsresult SetQuotingToFollow (PRBool aVal)
nsresult ConvertHTMLToText (nsFileSpec &aSigFile, nsString &aSigData)
nsresult ConvertTextToHTML (nsFileSpec &aSigFile, nsString &aSigData)
PRBool IsEmbeddedObjectSafe (const char *originalScheme, const char *originalHost, const char *originalPath, nsIDOMNode *object)
nsresult ResetUrisForEmbeddedObjects ()
nsresult TagEmbeddedObjects (nsIEditorMailSupport *aMailEditor)
nsresult LoadDataFromFile (nsFileSpec &fSpec, nsString &sigData, PRBool aAllowUTF8=PR_TRUE, PRBool aAllowUTF16=PR_TRUE)
nsresult GetIdentity (nsIMsgIdentity **aIdentity)
nsresult _SendMsg (MSG_DeliverMode deliverMode, nsIMsgIdentity *identity, const char *accountKey, PRBool entityConversionDone)
nsresult CreateMessage (const char *originalMsgURI, MSG_ComposeType type, nsIMsgCompFields *compFields)
void CleanUpRecipients (nsString &recipients)
nsresult GetABDirectories (const nsACString &dirUri, nsISupportsArray *directoriesArray, PRBool searchSubDirectory)
nsresult BuildMailListArray (nsIAddrDatabase *database, nsIAbDirectory *parentDir, nsISupportsArray *array)
nsresult GetMailListAddresses (nsString &name, nsISupportsArray *mailListArray, nsISupportsArray **addresses)
nsresult TagConvertible (nsIDOMNode *node, PRInt32 *_retval)
nsresult _BodyConvertible (nsIDOMNode *node, PRInt32 *_retval)
PRBool IsLastWindow ()

Private Attributes

nsCString mQuoteCharset
nsCString mOriginalMsgURI
PRInt32 mWhatHolder
nsCString m_folderName
PRBool mConvertStructs
nsCOMPtr< nsIEditorm_editor
nsIDOMWindowInternalm_window
nsCOMPtr< nsIBaseWindowm_baseWindow
nsMsgCompFieldsm_compFields
nsCOMPtr< nsIMsgIdentitym_identity
PRBool m_composeHTML
QuotingOutputStreamListenermQuoteStreamListener
nsCOMPtr< nsIOutputStreammBaseStream
nsCOMPtr
< nsIMsgComposeRecyclingListener
mRecyclingListener
PRBool mRecycledWindow
nsCOMPtr< nsIMsgSendmMsgSend
nsCOMPtr< nsIMsgProgressmProgress
nsString mCiteReference
nsCOMPtr< nsIMsgQuotemQuote
PRBool mQuotingToFollow
MSG_ComposeType mType
nsCOMPtr< nsISupportsArraymStateListeners
PRBool mCharsetOverride
PRBool mDeleteDraft
nsMsgDispositionState mDraftDisposition
nsCOMPtr< nsIMsgDBHdrmOrigMsgHdr
nsCOMPtr< nsIMsgSendListenermExternalSendListener
nsCString mSmtpPassword
PRBool mInsertingQuotedContent

Friends

class QuotingOutputStreamListener
class nsMsgComposeSendListener

Detailed Description

Definition at line 69 of file nsMsgCompose.h.


Constructor & Destructor Documentation

Definition at line 215 of file nsMsgCompose.cpp.

{
#if defined(DEBUG_ducarroz)
  printf("CREATE nsMsgCompose: %x\n", this);
#endif

  mQuotingToFollow = PR_FALSE;
  mInsertingQuotedContent = PR_FALSE;
  mWhatHolder = 1;
  m_window = nsnull;
  m_editor = nsnull;
  mQuoteStreamListener=nsnull;
  mCharsetOverride = PR_FALSE;
  mDeleteDraft = PR_FALSE;
  m_compFields = nsnull;    //m_compFields will be set during nsMsgCompose::Initialize
  mType = nsIMsgCompType::New;

  // For TagConvertible
  // Read and cache pref
  mConvertStructs = PR_FALSE;
  nsCOMPtr<nsIPrefBranch> prefBranch (do_GetService(NS_PREFSERVICE_CONTRACTID));
  if (prefBranch)
    prefBranch->GetBoolPref("converter.html2txt.structs", &mConvertStructs);

  m_composeHTML = PR_FALSE;
  mRecycledWindow = PR_TRUE;
}

Here is the call graph for this function:

Definition at line 244 of file nsMsgCompose.cpp.

{
#if defined(DEBUG_ducarroz)
  printf("DISPOSE nsMsgCompose: %x\n", this);
#endif

  NS_IF_RELEASE(m_compFields);
  NS_IF_RELEASE(mQuoteStreamListener);
}

Member Function Documentation

nsresult nsMsgCompose::_BodyConvertible ( nsIDOMNode node,
PRInt32 _retval 
) [private]

Definition at line 4821 of file nsMsgCompose.cpp.

{
    NS_ENSURE_TRUE(node && _retval, NS_ERROR_NULL_POINTER);

    nsresult rv;
    PRInt32 result;

    // Check this node
    rv = TagConvertible(node, &result);
    if (NS_FAILED(rv))
        return rv;

    // Walk tree recursively to check the children
    PRBool hasChild;
    if (NS_SUCCEEDED(node->HasChildNodes(&hasChild)) && hasChild)
    {
      nsCOMPtr<nsIDOMNodeList> children;
      if (NS_SUCCEEDED(node->GetChildNodes(getter_AddRefs(children)))
          && children)
      {
        PRUint32 nbrOfElements;
        rv = children->GetLength(&nbrOfElements);
        for (PRUint32 i = 0; NS_SUCCEEDED(rv) && i < nbrOfElements; i++)
        {
          nsCOMPtr<nsIDOMNode> pItem;
          if (NS_SUCCEEDED(children->Item(i, getter_AddRefs(pItem)))
              && pItem)
          {
            PRInt32 curresult;
            rv = _BodyConvertible(pItem, &curresult);
            if (NS_SUCCEEDED(rv) && curresult > result)
              result = curresult;
          }
        }
      }
    }

    *_retval = result;
    return rv;
}

Here is the call graph for this function:

nsresult nsMsgCompose::_SendMsg ( MSG_DeliverMode  deliverMode,
nsIMsgIdentity identity,
const char *  accountKey,
PRBool  entityConversionDone 
) [private]

Definition at line 904 of file nsMsgCompose.cpp.

{
  nsresult rv = NS_OK;

  // clear saved message id if sending, so we don't send out the same message-id.
  if (deliverMode == nsIMsgCompDeliverMode::Now || deliverMode == nsIMsgCompDeliverMode::Later)
    m_compFields->SetMessageId("");

  if (m_compFields && identity) 
  {
    // Pref values are supposed to be stored as UTF-8, so no conversion
    nsXPIDLCString email;
    nsXPIDLString fullName;
    nsXPIDLString organization;

    identity->GetEmail(getter_Copies(email));
    identity->GetFullName(getter_Copies(fullName));
    identity->GetOrganization(getter_Copies(organization));

    char * sender = nsnull;
    nsCOMPtr<nsIMsgHeaderParser> parser (do_GetService(NS_MAILNEWS_MIME_HEADER_PARSER_CONTRACTID));
    if (parser) {
      // convert to UTF8 before passing to MakeFullAddress
      parser->MakeFullAddress(nsnull, NS_ConvertUCS2toUTF8(fullName).get(), email, &sender);
    }

  if (!sender)
    m_compFields->SetFrom(email);
  else
    m_compFields->SetFrom(sender);
  PR_FREEIF(sender);

    m_compFields->SetOrganization(organization);

#if defined(DEBUG_ducarroz) || defined(DEBUG_seth_)
  {
    printf("----------------------------\n");
    printf("--  Sending Mail Message  --\n");
    printf("----------------------------\n");
    printf("from: %s\n", m_compFields->GetFrom());
    printf("To: %s  Cc: %s  Bcc: %s\n", m_compFields->GetTo(), m_compFields->GetCc(), m_compFields->GetBcc());
    printf("Newsgroups: %s\n", m_compFields->GetNewsgroups());
    printf("Subject: %s  \nMsg: %s\n", m_compFields->GetSubject(), m_compFields->GetBody());
    nsCOMPtr<nsISupportsArray> attachmentsArray;
    m_compFields->GetAttachmentsArray(getter_AddRefs(attachmentsArray));
    if (attachmentsArray)
    {
      PRUint32 i;
      PRUint32 attachmentCount = 0;
      attachmentsArray->Count(&attachmentCount);

      nsCOMPtr<nsIMsgAttachment> element;
      for (i = 0; i < attachmentCount; i ++)
      {
        attachmentsArray->QueryElementAt(i, NS_GET_IID(nsIMsgAttachment), getter_AddRefs(element));
        if (element)
        {
          nsAutoString name;
          nsXPIDLCString url;
          element->GetName(name);
          element->GetUrl(getter_Copies(url));
          printf("Attachment %d: %s - %s\n",i + 1, NS_ConvertUTF16toUTF8(name).get(), url.get());
        }
      }
    }
    printf("----------------------------\n");
  }
#endif //DEBUG

    mMsgSend = do_CreateInstance(NS_MSGSEND_CONTRACTID);
    if (mMsgSend)
    {
      PRBool      newBody = PR_FALSE;
      char        *bodyString = (char *)m_compFields->GetBody();
      PRInt32     bodyLength;
      const char  attachment1_type[] = TEXT_HTML;  // we better be "text/html" at this point

      if (!entityConversionDone)
      {
        // Convert body to mail charset
        char      *outCString;

        if (  bodyString && *bodyString )
        {
          // Apply entity conversion then convert to a mail charset. 
          PRBool isAsciiOnly;
          rv = nsMsgI18NSaveAsCharset(attachment1_type, m_compFields->GetCharacterSet(), 
                                      NS_ConvertUTF8toUTF16(bodyString).get(), &outCString,
                                      nsnull, &isAsciiOnly);
          if (NS_SUCCEEDED(rv)) 
          {
            if (m_compFields->GetForceMsgEncoding())
              isAsciiOnly = PR_FALSE;

            m_compFields->SetBodyIsAsciiOnly(isAsciiOnly);
            bodyString = outCString;
            newBody = PR_TRUE;
          }
        }
      }

      bodyLength = PL_strlen(bodyString);

      // Create the listener for the send operation...
      nsCOMPtr<nsIMsgComposeSendListener> composeSendListener = do_CreateInstance(NS_MSGCOMPOSESENDLISTENER_CONTRACTID);
      if (!composeSendListener)
        return NS_ERROR_OUT_OF_MEMORY;

      // right now, AutoSaveAsDraft is identical to SaveAsDraft as
      // far as the msg send code is concerned. This way, we don't have
      // to add an nsMsgDeliverMode for autosaveasdraft, and add cases for
      // it in the msg send code.
      if (deliverMode == nsIMsgCompDeliverMode::AutoSaveAsDraft)
        deliverMode = nsIMsgCompDeliverMode::SaveAsDraft;

      composeSendListener->SetMsgCompose(this);
      composeSendListener->SetDeliverMode(deliverMode);

      if (mProgress)
      {
        nsCOMPtr<nsIWebProgressListener> progressListener = do_QueryInterface(composeSendListener);
        mProgress->RegisterListener(progressListener);
      }

      // If we are composing HTML, then this should be sent as
      // multipart/related which means we pass the editor into the
      // backend...if not, just pass nsnull
      //
      nsCOMPtr<nsIMsgSendListener> sendListener = do_QueryInterface(composeSendListener);
      rv = mMsgSend->CreateAndSendMessage(
                    m_composeHTML ? m_editor.get() : nsnull,
                    identity,
                    accountKey,
                    m_compFields, 
                    PR_FALSE,                           // PRBool                            digest_p,
                    PR_FALSE,                           // PRBool                            dont_deliver_p,
                    (nsMsgDeliverMode)deliverMode,      // nsMsgDeliverMode                  mode,
                    nsnull,                             // nsIMsgDBHdr                       *msgToReplace, 
                    m_composeHTML?TEXT_HTML:TEXT_PLAIN, // const char                        *attachment1_type,
                    bodyString,                         // const char                        *attachment1_body,
                    bodyLength,                         // PRUint32                          attachment1_body_length,
                    nsnull,                             // const struct nsMsgAttachmentData  *attachments,
                    nsnull,                             // const struct nsMsgAttachedFile    *preloaded_attachments,
                    nsnull,                             // nsMsgSendPart                     *relatedPart,
                    m_window,                           // nsIDOMWindowInternal              *parentWindow;
                    mProgress,                          // nsIMsgProgress                    *progress,
                    sendListener,                       // listener
                    mSmtpPassword.get(),
                    mOriginalMsgURI,
                    mType);

      // Cleanup converted body...
      if (newBody)
        PR_FREEIF(bodyString);
    }
    else
        rv = NS_ERROR_FAILURE;
  }
  else
    rv = NS_ERROR_NOT_INITIALIZED;

  if (NS_FAILED(rv))
    NotifyStateListeners(eComposeProcessDone,rv);

  return rv;
}

Here is the call graph for this function:

void nsIMsgCompose::abort ( ) [inherited]
AUTF8String nsIMsgCompose::AttachmentPrettyName ( in string  url,
in string  charset 
) [inherited]
nsresult nsMsgCompose::BuildMailListArray ( nsIAddrDatabase database,
nsIAbDirectory parentDir,
nsISupportsArray array 
) [private]

Definition at line 4134 of file nsMsgCompose.cpp.

{
  nsresult rv;

  nsCOMPtr<nsIAbDirectory> directory;
  nsCOMPtr<nsISimpleEnumerator> subDirectories;

  if (NS_SUCCEEDED(parentDir->GetChildNodes(getter_AddRefs(subDirectories))) && subDirectories)
  {
    nsCOMPtr<nsISupports> item;
    PRBool hasMore;
    while (NS_SUCCEEDED(rv = subDirectories->HasMoreElements(&hasMore)) && hasMore)
    {
      if (NS_SUCCEEDED(subDirectories->GetNext(getter_AddRefs(item))))
      {
        directory = do_QueryInterface(item, &rv);
        if (NS_SUCCEEDED(rv))
        {
          PRBool bIsMailList;

          if (NS_SUCCEEDED(directory->GetIsMailList(&bIsMailList)) && bIsMailList)
          {
            nsXPIDLString listName;
            nsXPIDLString listDescription;

            directory->GetDirName(getter_Copies(listName));
            directory->GetDescription(getter_Copies(listDescription));

            nsMsgMailList* mailList = new nsMsgMailList(nsAutoString((const PRUnichar*)listName),
                  nsAutoString((const PRUnichar*)listDescription), directory);
            if (!mailList)
              return NS_ERROR_OUT_OF_MEMORY;
            NS_ADDREF(mailList);

            rv = array->AppendElement(mailList);
            if (NS_FAILED(rv))
              return rv;

            NS_RELEASE(mailList);
          }
        }
      }
    }
  }
  return rv;
}

Here is the call graph for this function:

unsigned long nsIMsgCompose::CheckAndPopulateRecipients ( in boolean  populateMailList,
in boolean  returnNonHTMLRecipients,
out wstring  nonHTMLRecipients 
) [inherited]
boolean nsIMsgCompose::checkCharsetConversion ( in nsIMsgIdentity  identity,
out string  fallbackCharset 
) [inherited]
void nsMsgCompose::CleanUpRecipients ( nsString recipients) [private]

Definition at line 2896 of file nsMsgCompose.cpp.

{
  PRUint16 i;
  PRBool startANewRecipient = PR_TRUE;
  PRBool removeBracket = PR_FALSE;
  nsAutoString newRecipient;
  PRUnichar aChar;

  for (i = 0; i < recipients.Length(); i ++)
  {
    aChar = recipients[i];
    switch (aChar)
    {
      case '<'  :
        if (startANewRecipient)
          removeBracket = PR_TRUE;
        else
          newRecipient += aChar;
        startANewRecipient = PR_FALSE;
        break;

      case '>'  :
        if (removeBracket)
          removeBracket = PR_FALSE;
        else
          newRecipient += aChar;
        break;

      case ' '  :
        newRecipient += aChar;
        break;

      case ','  :
        newRecipient += aChar;
        startANewRecipient = PR_TRUE;
        removeBracket = PR_FALSE;
        break;

      default   :
        newRecipient += aChar;
        startANewRecipient = PR_FALSE;
        break;
    } 
  }
  recipients = newRecipient;
}
void nsIMsgCompose::CloseWindow ( in boolean  reclycleIt) [inherited]
void nsIMsgCompose::convertAndLoadComposeWindow ( in nsStringRef  aPrefix,
in nsStringRef  aBuf,
in nsStringRef  aSignature,
in boolean  aQuoted,
in boolean  aHTMLEditor 
) [inherited]
nsresult nsMsgCompose::ConvertHTMLToText ( nsFileSpec aSigFile,
nsString aSigData 
) [private]

Definition at line 3579 of file nsMsgCompose.cpp.

{
  nsresult    rv;
  nsAutoString    origBuf;

  rv = LoadDataFromFile(aSigFile, origBuf);
  if (NS_FAILED(rv))
    return rv;

  ConvertBufToPlainText(origBuf,PR_FALSE);
  aSigData = origBuf;
  return NS_OK;
}

Here is the call graph for this function:

nsresult nsMsgCompose::ConvertTextToHTML ( nsFileSpec aSigFile,
nsString aSigData 
) [private]

Definition at line 3594 of file nsMsgCompose.cpp.

{
  nsresult    rv;
  nsAutoString    origBuf;

  rv = LoadDataFromFile(aSigFile, origBuf);
  if (NS_FAILED(rv))
    return rv;

  // Ok, once we are here, we need to escape the data to make sure that
  // we don't do HTML stuff with plain text sigs.
  //
  PRUnichar *escaped = nsEscapeHTML2(origBuf.get());
  if (escaped) 
  {
    aSigData.Append(escaped);
    nsCRT::free(escaped);
  }
  else
  {
    aSigData.Append(origBuf);
  }

  return NS_OK;
}

Here is the call graph for this function:

nsresult nsMsgCompose::CreateMessage ( const char *  originalMsgURI,
MSG_ComposeType  type,
nsIMsgCompFields compFields 
) [private]

Definition at line 1561 of file nsMsgCompose.cpp.

{
  nsresult rv = NS_OK;

  mType = type;
  mDraftDisposition = nsIMsgFolder::nsMsgDispositionState_None;

  mDeleteDraft = (type == nsIMsgCompType::Draft);
  nsCAutoString msgUri(originalMsgURI);
  // check if we're dealing with an opened .eml file msg
  PRBool fileUrl = StringBeginsWith(msgUri, NS_LITERAL_CSTRING("file:"));
  if (fileUrl)
  {
    // strip out ?type=application/x-message-display because it confuses libmime
    PRInt32 typeIndex = msgUri.Find("?type=application/x-message-display");
    if (typeIndex != kNotFound)
    {
      msgUri.Cut(typeIndex, sizeof("?type=application/x-message-display") - 1);
      // we also need to replace the next '&' with '?'
      if (msgUri.CharAt(typeIndex) == '&')
        msgUri.SetCharAt('?', typeIndex);
      originalMsgURI = msgUri.get();
    }
  }
  else // check if we're dealing with a displayed message/rfc822 attachment
  {
    PRInt32 typeIndex = msgUri.Find("&type=application/x-message-display");
    if (typeIndex != kNotFound)
    {
      msgUri.Cut(typeIndex, sizeof("&type=application/x-message-display") - 1);
      // nsURLFetcher will check for "realtype=message/rfc822" and will set the
      // content type to message/rfc822 in the forwarded message.
      msgUri.Append("&realtype=message/rfc822");
      originalMsgURI = msgUri.get();
    }
  }
  if (compFields)
  {
    NS_IF_RELEASE(m_compFields);
    m_compFields = NS_REINTERPRET_CAST(nsMsgCompFields*, compFields);
    NS_ADDREF(m_compFields);
  }
  else
  {
    NS_NEWXPCOM(m_compFields, nsMsgCompFields);
    if (m_compFields)
      NS_ADDREF(m_compFields);
    else
      return NS_ERROR_OUT_OF_MEMORY;
  }

  if (m_identity)
  {
      nsXPIDLCString::const_iterator start, end;

      /* Setup reply-to field */
      nsXPIDLCString replyTo;
      m_identity->GetReplyTo(getter_Copies(replyTo));
      if (replyTo && *(const char *)replyTo)
      {
        nsXPIDLCString replyToStr;
        replyToStr.Assign(m_compFields->GetReplyTo());

        replyToStr.BeginReading(start);
        replyToStr.EndReading(end);

        if (FindInReadable(replyTo, start, end) == PR_FALSE) {
          if (replyToStr.Length() > 0)
            replyToStr.Append(',');
          replyToStr.Append(replyTo);
        }
        m_compFields->SetReplyTo(replyToStr.get());
      }

      /* Setup bcc field */
      PRBool doBcc;
      m_identity->GetDoBcc(&doBcc);
      if (doBcc) 
      {
        nsXPIDLCString bccStr;
        bccStr.Assign(m_compFields->GetBcc());

          bccStr.BeginReading(start);
          bccStr.EndReading(end);

          nsXPIDLCString bccList;
          m_identity->GetDoBccList(getter_Copies(bccList));
          if (FindInReadable(bccList, start, end) == PR_FALSE) {
            if (bccStr.Length() > 0)
              bccStr.Append(',');
            bccStr.Append(bccList);
          }

        m_compFields->SetBcc(bccStr.get());
      }
  }

  if (mType == nsIMsgCompType::Draft)
  {
    nsXPIDLCString curDraftIdURL;

    rv = m_compFields->GetDraftId(getter_Copies(curDraftIdURL));
    NS_ASSERTION((NS_SUCCEEDED(rv) && (curDraftIdURL)), "RemoveCurrentDraftMessage can't get draft id");

    // Skip if no draft id (probably a new draft msg).
    if (NS_SUCCEEDED(rv) && curDraftIdURL.get() && strlen(curDraftIdURL.get()))
    { 
      nsCOMPtr <nsIMsgDBHdr> msgDBHdr;
      rv = GetMsgDBHdrFromURI(curDraftIdURL, getter_AddRefs(msgDBHdr));
      NS_ASSERTION(NS_SUCCEEDED(rv), "RemoveCurrentDraftMessage can't get msg header DB interface pointer.");
      if (msgDBHdr)
      {
        nsXPIDLCString queuedDisposition;
        msgDBHdr->GetStringProperty(QUEUED_DISPOSITION_PROPERTY, getter_Copies(queuedDisposition));
        nsXPIDLCString originalMsgURIs;
        msgDBHdr->GetStringProperty(ORIG_URI_PROPERTY, getter_Copies(originalMsgURIs));
        mOriginalMsgURI = originalMsgURIs;
        if (!queuedDisposition.IsEmpty())
        {
          if (queuedDisposition.Equals("replied"))
             mDraftDisposition = nsIMsgFolder::nsMsgDispositionState_Replied;
          else if (queuedDisposition.Equals("forward"))
             mDraftDisposition = nsIMsgFolder::nsMsgDispositionState_Forwarded;
        }
      }
    }
  }

  // If we don't have an original message URI, nothing else to do...
  if (!originalMsgURI || *originalMsgURI == 0)
    return NS_OK;

  // store the original message URI so we can extract it after we send the message to properly
  // mark any disposition flags like replied or forwarded on the message.
  mOriginalMsgURI = originalMsgURI;

  // If we are forwarding inline, mime did already setup the compose fields therefore we should stop now
  if (type == nsIMsgCompType::ForwardInline )
  {
    // use send_default_charset if reply_in_default_charset is on.
    nsCOMPtr<nsIPrefBranch> prefs (do_GetService(NS_PREFSERVICE_CONTRACTID));
    if (prefs)
    {
      PRBool replyInDefault = PR_FALSE;
      prefs->GetBoolPref("mailnews.reply_in_default_charset",
                         &replyInDefault);
      if (replyInDefault)
      {
        nsXPIDLString str;
        nsXPIDLCString charset;
        NS_GetLocalizedUnicharPreferenceWithDefault(prefs, "mailnews.send_default_charset",
                                                    EmptyString(), str);
        if (!str.IsEmpty())
        {
          LossyCopyUTF16toASCII(str, charset);
          m_compFields->SetCharacterSet(charset);
        }
      }
    }
    return rv;
  }

  char *uriList = PL_strdup(originalMsgURI);
  if (!uriList)
    return NS_ERROR_OUT_OF_MEMORY;

  nsCOMPtr<nsIMimeConverter> mimeConverter = do_GetService(NS_MIME_CONVERTER_CONTRACTID);

  nsXPIDLCString charset;
  // use a charset of the original message
  nsXPIDLCString mailCharset;
  PRBool charsetOverride = PR_FALSE;
  GetTopmostMsgWindowCharacterSet(mailCharset, &mCharsetOverride);
  if (!mailCharset.IsEmpty())
  {
    charset = mailCharset;
    charsetOverride = mCharsetOverride;
  }
#ifdef DEBUG_jungshik
  printf ("charset=%s\n", charset.get());
  printf ("charsetOverride=%d\n", charsetOverride);
#endif

  // although the charset in which to _send_ the message might change,
  // the original message will be parsed for quoting using the charset it is
  // now displayed with
  mQuoteCharset = charset;

  PRBool isFirstPass = PR_TRUE;
  char *uri = uriList;
  char *nextUri;
  do 
  {
    nextUri = strstr(uri, "://");
    if (nextUri)
    {
      // look for next ://, and then back up to previous ','
      nextUri = strstr(nextUri + 1, "://");
      if (nextUri)
      {
        *nextUri = '\0';
        char *saveNextUri = nextUri;
        nextUri = strrchr(uri, ',');
        if (nextUri)
          *nextUri = '\0';
        *saveNextUri = ':';
      }
    }

    nsCOMPtr <nsIMsgDBHdr> msgHdr;
    if (mOrigMsgHdr)
      msgHdr = mOrigMsgHdr;
    else
    {
      rv = GetMsgDBHdrFromURI(uri, getter_AddRefs(msgHdr));
      NS_ENSURE_SUCCESS(rv,rv);
    }
    if (msgHdr)
    {
      nsXPIDLString subject;
      nsXPIDLCString decodedCString;

      if (!charsetOverride && charset.IsEmpty())
      {
        rv = msgHdr->GetCharset(getter_Copies(charset));
        if (NS_FAILED(rv)) return rv;
      }

      // save the charset of a message being replied to because
      // we need to use it when decoding RFC-2047-encoded author name
      // with |charsetOverride == PR_TRUE|
      nsCAutoString originCharset(charset); 

      // use send_default_charset if reply_in_default_charset is on.
      nsCOMPtr<nsIPrefBranch> prefs (do_GetService(NS_PREFSERVICE_CONTRACTID));
      if (prefs)
      {
        PRBool replyInDefault = PR_FALSE;
        prefs->GetBoolPref("mailnews.reply_in_default_charset",
                           &replyInDefault);
        if (replyInDefault) {
          nsXPIDLString str;
          NS_GetLocalizedUnicharPreferenceWithDefault(prefs, "mailnews.send_default_charset",
                                                      EmptyString(), str);
          if (!str.IsEmpty())
            LossyCopyUTF16toASCII(str, charset);
        }
      }

      // No matter what, we should block x-windows-949 (our internal name)
      // from being used for outgoing emails (bug 234958)
      if (charset.Equals("x-windows-949",
            nsCaseInsensitiveCStringComparator()))
        charset = "EUC-KR";

      // get an original charset, used for a label, UTF-8 is used for the internal processing
      if (isFirstPass && !charset.IsEmpty())
        m_compFields->SetCharacterSet(charset);

      nsXPIDLCString subjectCStr;
      (void) msgHdr->GetSubject(getter_Copies(subjectCStr));
      rv = mimeConverter->DecodeMimeHeader(subjectCStr,
                getter_Copies(decodedCString),
                originCharset.get(), charsetOverride);
      if (NS_FAILED(rv)) return rv;

      CopyUTF8toUTF16(decodedCString, subject);

      // Check if (was: is present in the subject
      nsAString::const_iterator wasStart, wasEnd;
      subject.BeginReading(wasStart);
      subject.EndReading(wasEnd);
      PRBool wasFound = RFindInReadable(NS_LITERAL_STRING(" (was:"), wasStart, wasEnd);
      PRBool strip = PR_TRUE;

      if (wasFound) {
        // Check the number of references, to check if was: should be stripped
        // First, assume that it should be stripped; the variable will be set to
        // false later if stripping should not happen.
        PRUint16 numRef;
        msgHdr->GetNumReferences(&numRef);
        if (numRef) {
          // If there are references, look for the first message in the thread
          // firstly, get the database via the folder
          nsCOMPtr<nsIMsgFolder> folder;
          msgHdr->GetFolder(getter_AddRefs(folder));
          if (folder) {
            nsCOMPtr<nsIMsgDatabase> db;
            folder->GetMsgDatabase(nsnull, getter_AddRefs(db));

            if (db) {
              nsCAutoString reference;
              msgHdr->GetStringReference(0, reference);

              nsCOMPtr<nsIMsgDBHdr> refHdr;
              db->GetMsgHdrForMessageID(reference.get(), getter_AddRefs(refHdr));

              if (refHdr) {
                nsXPIDLCString refSubject;
                rv = refHdr->GetSubject(getter_Copies(refSubject));
                if (NS_SUCCEEDED(rv)) {
                  nsACString::const_iterator start, end;
                  refSubject.BeginReading(start);
                  refSubject.EndReading(end);
                  if (FindInReadable(NS_LITERAL_CSTRING(" (was:"), start, end))
                    strip = PR_FALSE;
                }
              }
            }
          }
        }
        else
          strip = PR_FALSE;
      }

      if (strip && wasFound) {
        // Strip off the "(was: old subject)" part
        nsAString::const_iterator start;
        subject.BeginReading(start);
        subject.Assign(Substring(start, wasStart));
      }

      switch (type)
      {
        default: break;
        case nsIMsgCompType::Reply :
        case nsIMsgCompType::ReplyAll:
        case nsIMsgCompType::ReplyToGroup:
        case nsIMsgCompType::ReplyToSender:
        case nsIMsgCompType::ReplyToSenderAndGroup:
          {
            if (!isFirstPass)       // safeguard, just in case...
            {
              PR_Free(uriList);
              return rv;
            }
            mQuotingToFollow = PR_TRUE;

            subject.Insert(NS_LITERAL_STRING("Re: "), 0);
            m_compFields->SetSubject(subject);

            nsXPIDLCString author, authorEmailAddress;
            msgHdr->GetAuthor(getter_Copies(author));
            nsCOMPtr<nsIMsgHeaderParser> parser (do_GetService(NS_MAILNEWS_MIME_HEADER_PARSER_CONTRACTID));
            if (parser) {
              // convert to UTF8 before passing to MakeFullAddress
              rv = parser->ExtractHeaderAddressMailboxes(nsnull, author.get(), 
                                                            getter_Copies(authorEmailAddress));
            }

            PRBool replyToSelfCheckAll = PR_FALSE;
            nsCOMPtr<nsIPrefBranch> prefBranch(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
            if (NS_SUCCEEDED(rv)) 
              prefBranch->GetBoolPref("mailnews.reply_to_self_check_all_ident", &replyToSelfCheckAll);

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

            nsCOMPtr<nsISupportsArray> identities;
            nsXPIDLCString accountKey;
            msgHdr->GetAccountKey(getter_Copies(accountKey));
            if(replyToSelfCheckAll)
            {
              // check all avaliable identities if the pref was set
              accountManager->GetAllIdentities(getter_AddRefs(identities));
            }
            else if (!accountKey.IsEmpty())
            {
               // check headers to see which account the message came in from (only works for pop3)
              nsCOMPtr<nsIMsgAccount> account;
              accountManager->GetAccount(accountKey, getter_AddRefs(account));

              if(account)
                account->GetIdentities(getter_AddRefs(identities));
            } 
            else 
            {
              // check identities only for the server of the folder that the message is in 
              nsCOMPtr <nsIMsgFolder> msgFolder;
              rv = msgHdr->GetFolder(getter_AddRefs(msgFolder));

              if (NS_SUCCEEDED(rv) && msgFolder){ 
                nsCOMPtr<nsIMsgIncomingServer> nsIMsgIncomingServer;
                rv = msgFolder->GetServer(getter_AddRefs(nsIMsgIncomingServer));

                if(NS_SUCCEEDED(rv) && nsIMsgIncomingServer) 
                  accountManager->GetIdentitiesForServer(nsIMsgIncomingServer, getter_AddRefs(identities));
              }
            }

            PRBool isReplyToOwnMsg = PR_FALSE;
            if(identities)
            {
              // go through the identities to see if any of them is the author of the email
              nsCOMPtr<nsIMsgIdentity> lookupIdentity;

              PRUint32 count = 0;
              identities->Count(&count);

              for (PRUint32 i = 0; i < count; i++) 
              {
                rv = identities->QueryElementAt(i, NS_GET_IID(nsIMsgIdentity),
                                          getter_AddRefs(lookupIdentity));
                if (NS_FAILED(rv))
                  continue;

                nsXPIDLCString curIdentityEmail;
                lookupIdentity->GetEmail(getter_Copies(curIdentityEmail));
                if (curIdentityEmail.Equals(authorEmailAddress))
                {
                  isReplyToOwnMsg = PR_TRUE;
                  break;
                }
              }
            }

            nsXPIDLCString toField;
            if (isReplyToOwnMsg)
              msgHdr->GetRecipients(getter_Copies(toField));
            else
              toField.Assign(author);

            rv = mimeConverter->DecodeMimeHeader(toField,
                getter_Copies(decodedCString),
                originCharset.get(), charsetOverride);
            if (NS_SUCCEEDED(rv) && decodedCString)
              m_compFields->SetTo(decodedCString);
            else
              m_compFields->SetTo(toField);

            // Setup quoting callbacks for later...
            mWhatHolder = 1;
            break;
          }
        case nsIMsgCompType::ForwardAsAttachment:
          {
            PRUint32 flags;

            msgHdr->GetFlags(&flags);
            if (flags & MSG_FLAG_HAS_RE)
              subject.Insert(NS_LITERAL_STRING("Re: "), 0);

            // Setup quoting callbacks for later...
            mQuotingToFollow = PR_FALSE;  //We don't need to quote the original message.
            nsCOMPtr<nsIMsgAttachment> attachment = do_CreateInstance(NS_MSGATTACHMENT_CONTRACTID, &rv);
            if (NS_SUCCEEDED(rv) && attachment)
            {
              attachment->SetName(subject + NS_LITERAL_STRING(".eml"));
              attachment->SetUrl(uri);
              m_compFields->AddAttachment(attachment);
            }

            if (isFirstPass)
            {
              subject.Insert(NS_LITERAL_STRING("[Fwd: ").get(), 0);
              subject.Append(NS_LITERAL_STRING("]").get());
              m_compFields->SetSubject(subject); 
            }
            break;
          }
      }
    }
    isFirstPass = PR_FALSE;
    uri = nextUri + 1;
  }
  while (nextUri);
  PR_Free(uriList);
  return rv;
}

Here is the call graph for this function:

nsresult nsMsgCompose::GetABDirectories ( const nsACString &  dirUri,
nsISupportsArray directoriesArray,
PRBool  searchSubDirectory 
) [private]

Definition at line 4058 of file nsMsgCompose.cpp.

{
  static PRBool collectedAddressbookFound;
  if (dirUri.EqualsLiteral(kMDBDirectoryRoot))
    collectedAddressbookFound = PR_FALSE;

  nsresult rv = NS_OK;
  nsCOMPtr<nsIRDFService> rdfService (do_GetService("@mozilla.org/rdf/rdf-service;1", &rv));
  if (NS_FAILED(rv)) return rv;

  nsCOMPtr <nsIRDFResource> resource;
  rv = rdfService->GetResource(dirUri, getter_AddRefs(resource));
  if (NS_FAILED(rv)) return rv;

  // query interface 
  nsCOMPtr<nsIAbDirectory> directory(do_QueryInterface(resource, &rv));
  if (NS_FAILED(rv)) return rv;

  if (!searchSubDirectory)
      return rv;

  nsCOMPtr<nsISimpleEnumerator> subDirectories;
  if (NS_SUCCEEDED(directory->GetChildNodes(getter_AddRefs(subDirectories))) && subDirectories)
  {
    nsCOMPtr<nsISupports> item;
    PRBool hasMore;
    while (NS_SUCCEEDED(rv = subDirectories->HasMoreElements(&hasMore)) && hasMore)
    {
      if (NS_SUCCEEDED(subDirectories->GetNext(getter_AddRefs(item))))
      {
        directory = do_QueryInterface(item, &rv);
        if (NS_SUCCEEDED(rv))
        {
          PRBool bIsMailList;

          if (NS_SUCCEEDED(directory->GetIsMailList(&bIsMailList)) && bIsMailList)
            continue;

          nsCOMPtr<nsIRDFResource> source(do_QueryInterface(directory));

          nsXPIDLCString uri;
          // rv = directory->GetDirUri(getter_Copies(uri));
          rv = source->GetValue(getter_Copies(uri));
          NS_ENSURE_SUCCESS(rv, rv);

          PRInt32 pos;
          if (nsCRT::strcmp((const char *)uri, kPersonalAddressbookUri) == 0)
            pos = 0;
          else
          {
            PRUint32 count = 0;
            directoriesArray->Count(&count);

            if (PL_strcmp((const char *)uri, kCollectedAddressbookUri) == 0)
            {
              collectedAddressbookFound = PR_TRUE;
              pos = count;
            }
            else
            {
              if (collectedAddressbookFound && count > 1)
                pos = count - 1;
              else
                pos = count;
            }
          }

          directoriesArray->InsertElementAt(directory, pos);
          rv = GetABDirectories(uri, directoriesArray, PR_TRUE);
        }
      }
    }
  }
  return rv;
}

Here is the call graph for this function:

nsresult nsMsgCompose::GetIdentity ( nsIMsgIdentity **  aIdentity) [inline, private]

Definition at line 114 of file nsMsgCompose.h.

                                {
                                  *aIdentity = m_identity;
                                  return NS_OK;
                                }
nsresult nsMsgCompose::GetMailListAddresses ( nsString name,
nsISupportsArray mailListArray,
nsISupportsArray **  addresses 
) [private]

Definition at line 4182 of file nsMsgCompose.cpp.

{
  nsresult rv;
  nsCOMPtr<nsIEnumerator> enumerator;

  rv = mailListArray->Enumerate(getter_AddRefs(enumerator));
  if (NS_SUCCEEDED(rv))
  {
    for (rv = enumerator->First(); NS_SUCCEEDED(rv); rv = enumerator->Next())
    {
      nsMsgMailList* mailList;
      rv = enumerator->CurrentItem((nsISupports**)&mailList);
      if (NS_SUCCEEDED(rv) && mailList)
      {
        if (name.Equals(mailList->mFullName, nsCaseInsensitiveStringComparator()))
        {
          if (!mailList->mDirectory)
            return NS_ERROR_FAILURE;

          mailList->mDirectory->GetAddressLists(addressesArray);
          NS_RELEASE(mailList);
          return NS_OK;
        }
        NS_RELEASE(mailList);
      }
    }
  }

  return NS_ERROR_FAILURE;
}

Here is the call graph for this function:

void nsIMsgCompose::getQuotingToFollow ( out boolean  quotingToFollow) [inherited]
void nsIMsgCompose::initEditor ( in nsIEditor  editor,
in nsIDOMWindow  contentWindow 
) [inherited]

Init the editor THIS USED TO BE [noscript] Now, this is called after editor is created, which is triggered by loading startup url from JS.

The completion of document loading is detected by observing the "obs_documentCreated" command

PRBool nsMsgCompose::IsEmbeddedObjectSafe ( const char *  originalScheme,
const char *  originalHost,
const char *  originalPath,
nsIDOMNode object 
) [private]

Definition at line 312 of file nsMsgCompose.cpp.

{
  nsresult rv;

  nsCOMPtr<nsIDOMHTMLImageElement> image;
  nsCOMPtr<nsIDOMHTMLLinkElement> link;
  nsCOMPtr<nsIDOMHTMLAnchorElement> anchor;
  nsAutoString objURL;

  if (!object || !originalScheme || !originalPath) //having a null host is ok...
    return PR_FALSE;

  if ((image = do_QueryInterface(object)))
  {
    if (NS_FAILED(image->GetSrc(objURL)))
      return PR_FALSE;
  }
  else if ((link = do_QueryInterface(object)))
  {
    if (NS_FAILED(link->GetHref(objURL)))
      return PR_FALSE;
  }
  else if ((anchor = do_QueryInterface(object)))
  {
    if (NS_FAILED(anchor->GetHref(objURL)))
      return PR_FALSE;
  }
  else
    return PR_FALSE;

  if (!objURL.IsEmpty())
  {
    nsCOMPtr<nsIURI> uri;
    rv = NS_NewURI(getter_AddRefs(uri), objURL);
    if (NS_SUCCEEDED(rv) && uri)
    {
      nsCAutoString scheme;
      rv = uri->GetScheme(scheme);
      if (NS_SUCCEEDED(rv) && (nsCRT::strcasecmp(scheme.get(), originalScheme) == 0))
      {
        nsCAutoString host;
        rv = uri->GetAsciiHost(host);
        // mailbox url don't have a host therefore don't be too strict.
        if (NS_SUCCEEDED(rv) && (host.IsEmpty() || originalHost || (nsCRT::strcasecmp(host.get(), originalHost) == 0)))
        {
          nsCAutoString path;
          rv = uri->GetPath(path);
          if (NS_SUCCEEDED(rv))
          {
            const char * query = strrchr(path.get(), '?');
            if (query && nsCRT::strncasecmp(path.get(), originalPath, query - path.get()) == 0)
              return PR_TRUE; //This object is a part of the original message, we can send it safely.
          }
        }
      }
    }
  }

  return PR_FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1322 of file nsMsgCompose.cpp.

{
  nsresult rv;
  PRBool more;
  nsCOMPtr<nsIWindowMediator> windowMediator =
              do_GetService(NS_WINDOWMEDIATOR_CONTRACTID, &rv);
  if (NS_SUCCEEDED(rv))
  {
    nsCOMPtr<nsISimpleEnumerator> windowEnumerator;
    rv = windowMediator->GetEnumerator(nsnull,
               getter_AddRefs(windowEnumerator));
    if (NS_SUCCEEDED(rv))
    {
      nsCOMPtr<nsISupports> isupports;

      if (NS_SUCCEEDED(windowEnumerator->GetNext(getter_AddRefs(isupports))))
        if (NS_SUCCEEDED(windowEnumerator->HasMoreElements(&more)))
          return !more;
    }
  }
  return PR_TRUE;
}

Here is the call graph for this function:

nsresult nsMsgCompose::LoadDataFromFile ( nsFileSpec fSpec,
nsString sigData,
PRBool  aAllowUTF8 = PR_TRUE,
PRBool  aAllowUTF16 = PR_TRUE 
) [private]

Definition at line 3621 of file nsMsgCompose.cpp.

{
  PRInt32       readSize;
  PRInt32       nGot;
  char          *readBuf;
  char          *ptr;

  if (fSpec.IsDirectory()) {
    NS_ASSERTION(0,"file is a directory");
    return NS_MSG_ERROR_READING_FILE;  
  }

  nsInputFileStream tempFile(fSpec);
  if (!tempFile.is_open())
    return NS_MSG_ERROR_READING_FILE;  

  readSize = fSpec.GetFileSize();
  ptr = readBuf = (char *)PR_Malloc(readSize + 1);  if (!readBuf)
    return NS_ERROR_OUT_OF_MEMORY;
  memset(readBuf, 0, readSize + 1);

  while (readSize) {
    nGot = tempFile.read(ptr, readSize);
    if (nGot > 0) {
      readSize -= nGot;
      ptr += nGot;
    }
    else {
      readSize = 0;
    }
  }
  tempFile.close();

  nsCAutoString sigEncoding(nsMsgI18NParseMetaCharset(&fSpec));
  PRBool removeSigCharset = !sigEncoding.IsEmpty() && m_composeHTML;

  if (sigEncoding.IsEmpty()) {
    if (aAllowUTF8 && IsUTF8(nsDependentCString(readBuf))) {
      sigEncoding.Assign("UTF-8");
    }
    else if (sigEncoding.IsEmpty() && aAllowUTF16 &&
             fSpec.GetFileSize() % 2 == 0 && fSpec.GetFileSize() >= 2 &&
             ((readBuf[0] == char(0xFE) && readBuf[1] == char(0xFF)) ||
              (readBuf[0] == char(0xFF) && readBuf[1] == char(0xFE)))) {
      sigEncoding.Assign("UTF-16");
    }
    else {
      //default to platform encoding for plain text files w/o meta charset
      nsCAutoString textFileCharset;
      nsMsgI18NTextFileCharset(textFileCharset);
      sigEncoding.Assign(textFileCharset);
    }
  }

  nsCAutoString readStr(readBuf, fSpec.GetFileSize());
  PR_FREEIF(readBuf);

  if (NS_FAILED(ConvertToUnicode(sigEncoding.get(), readStr, sigData)))
    CopyASCIItoUTF16(readStr, sigData);

  //remove sig meta charset to allow user charset override during composition
  if (removeSigCharset)
  {
    nsAutoString metaCharset(NS_LITERAL_STRING("charset="));
    AppendASCIItoUTF16(sigEncoding, metaCharset);
    nsAString::const_iterator realstart, start, end;
    sigData.BeginReading(start);
    sigData.EndReading(end);
    realstart = start;
    if (FindInReadable(metaCharset, start, end,
                       nsCaseInsensitiveStringComparator()))
      sigData.Cut(Distance(realstart, start), Distance(start, end));
  }

  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsIMsgCompose::notifyStateListeners ( in TStateListenerNotification  aNotificationType,
in nsresult  aResult 
) [inherited]
void nsIMsgCompose::processSignature ( in nsIMsgIdentity  identity,
in boolean  aQuoted,
inout nsString  aMsgBody 
) [inherited]
void nsIMsgCompose::quoteMessage ( in string  msgURI) [inherited]
nsresult nsMsgCompose::QuoteOriginalMessage ( const char *  originalMsgURI,
PRInt32  what 
) [private]

Definition at line 2853 of file nsMsgCompose.cpp.

{
  nsresult    rv;

  mQuotingToFollow = PR_FALSE;

  // Create a mime parser (nsIStreamConverter)!
  mQuote = do_CreateInstance(NS_MSGQUOTE_CONTRACTID, &rv);
  if (NS_FAILED(rv) || !mQuote)
    return NS_ERROR_FAILURE;

  PRBool bAutoQuote = PR_TRUE;
  m_identity->GetAutoQuote(&bAutoQuote);

  nsCOMPtr <nsIMsgDBHdr> originalMsgHdr = mOrigMsgHdr;
  if (!originalMsgHdr)
  {
    rv = GetMsgDBHdrFromURI(originalMsgURI, getter_AddRefs(originalMsgHdr));
    NS_ENSURE_SUCCESS(rv, rv);
  }

  // Create the consumer output stream.. this will receive all the HTML from libmime
  mQuoteStreamListener =
    new QuotingOutputStreamListener(originalMsgURI, originalMsgHdr, what != 1, !bAutoQuote, m_identity,
                                    mQuoteCharset.get(), mCharsetOverride, PR_TRUE);

  if (!mQuoteStreamListener)
  {
#ifdef NS_DEBUG
    printf("Failed to create mQuoteStreamListener\n");
#endif
    return NS_ERROR_FAILURE;
  }
  NS_ADDREF(mQuoteStreamListener);

  mQuoteStreamListener->SetComposeObj(this);

  rv = mQuote->QuoteMessage(originalMsgURI, what != 1, mQuoteStreamListener, 
                            mCharsetOverride ? mQuoteCharset.get() : "", !bAutoQuote);
  return rv;
}

Here is the call graph for this function:

Definition at line 379 of file nsMsgCompose.cpp.

{
  nsCOMPtr<nsISupportsArray> aNodeList;
  PRUint32 numNodes;
  PRUint32 i;

  nsCOMPtr<nsIEditorMailSupport> mailEditor (do_QueryInterface(m_editor));
  if (!mailEditor)
    return NS_ERROR_FAILURE;

  nsresult rv = mailEditor->GetEmbeddedObjects(getter_AddRefs(aNodeList));
  if ((NS_FAILED(rv) || (!aNodeList)))
    return NS_ERROR_FAILURE;

  if (NS_FAILED(aNodeList->Count(&numNodes)))
    return NS_ERROR_FAILURE;

  nsCOMPtr<nsIDOMNode> node;
  nsXPIDLCString curDraftIdURL;

  rv = m_compFields->GetDraftId(getter_Copies(curDraftIdURL));
  NS_ASSERTION((NS_SUCCEEDED(rv) && (curDraftIdURL)), "RemoveCurrentDraftMessage can't get draft id");

  // Skip if no draft id (probably a new draft msg).
  if (NS_SUCCEEDED(rv) && mMsgSend && !curDraftIdURL.IsEmpty())
  {
    // we don't currently handle imap urls
    if (StringBeginsWith(curDraftIdURL, NS_LITERAL_CSTRING("imap-message")))
      return NS_OK;

    nsCOMPtr <nsIMsgDBHdr> msgDBHdr;
    rv = GetMsgDBHdrFromURI(curDraftIdURL, getter_AddRefs(msgDBHdr));
    NS_ASSERTION(NS_SUCCEEDED(rv), "RemoveCurrentDraftMessage can't get msg header DB interface pointer.");
    if (NS_SUCCEEDED(rv) && msgDBHdr)
    {
      nsMsgKey oldDraftKey;

      // build up the old and new ?number= parts. This code assumes it is 
      // called *before* RemoveCurrentDraftMessage, so that curDraftIdURL
      // is the previous draft.
      // This code currently only works for local mail folders.
      // For imap folders, the url looks like <folder>%3E<UID>?part=...
      // We could handle the imap case as well, but it turns out 
      // not to be so important because the old message is still on
      // the imap server. If it turns out to be a problem, we can
      // deal with imap urls as well.
      msgDBHdr->GetMessageKey(&oldDraftKey);
      nsAutoString oldNumberPart(NS_LITERAL_STRING("?number="));
      oldNumberPart.AppendInt(oldDraftKey);
      nsAutoString newNumberPart;
      nsMsgKey newMsgKey;
      mMsgSend->GetMessageKey(&newMsgKey);
      newNumberPart.AppendInt(newMsgKey);

      nsCOMPtr<nsIDOMElement> domElement;
      for (i = 0; i < numNodes; i ++)
      {
        domElement = do_QueryElementAt(aNodeList, i);
        if (!domElement)
          continue;

        nsCOMPtr<nsIDOMHTMLImageElement> image = do_QueryInterface(domElement);
        if (!image)
          continue;
        // do we care about anything besides images?
        nsAutoString objURL;
        image->GetSrc(objURL);
        // the objURL is the full path to the mailbox, 
        // e.g., mailbox:///C/Documents%20Settings.../Local%20Folders/Drafts?number=
        // Find the ?number= part of the uri, and replace the
        // old number with the new msg key.

        PRInt32 numberIndex = objURL.Find(oldNumberPart);
        if (numberIndex != kNotFound)
        {
          objURL.Replace(numberIndex + 8, oldNumberPart.Length() - 8, newNumberPart);
          image->SetSrc(objURL);
        }
      }
    }
  }

  return NS_OK;
}

Here is the call graph for this function:

void nsIMsgCompose::SendMsg ( in MSG_DeliverMode  deliverMode,
in nsIMsgIdentity  identity,
in string  accountKey,
in nsIMsgWindow  aMsgWindow,
in nsIMsgProgress  progress 
) [inherited]
void nsIMsgCompose::setCiteReference ( in nsString  citeReference) [inherited]
void nsIMsgCompose::SetDocumentCharset ( in string  charset) [inherited]

Definition at line 758 of file nsMsgCompose.cpp.

{
  mQuotingToFollow = aVal;
  return NS_OK;
}
nsresult nsMsgCompose::TagConvertible ( nsIDOMNode node,
PRInt32 _retval 
) [private]

Definition at line 4596 of file nsMsgCompose.cpp.

{
    nsresult rv;

    *_retval = nsIMsgCompConvertible::No;

    PRUint16 nodeType;
    rv = node->GetNodeType(&nodeType);
    if (NS_FAILED(rv))
      return rv;

    nsAutoString element;
    rv = node->GetNodeName(element);
    if (NS_FAILED(rv))
      return rv;

    nsCOMPtr<nsIDOMNode> pItem;
    if      (
              nodeType == nsIDOMNode::TEXT_NODE ||
              element.LowerCaseEqualsLiteral("br") ||
              element.LowerCaseEqualsLiteral("p") ||
              element.LowerCaseEqualsLiteral("pre") ||
              element.LowerCaseEqualsLiteral("tt") ||
              element.LowerCaseEqualsLiteral("html") ||
              element.LowerCaseEqualsLiteral("head") ||
              element.LowerCaseEqualsLiteral("title")
            )
    {
      *_retval = nsIMsgCompConvertible::Plain;
    }
    else if (
              //element.LowerCaseEqualsLiteral("blockquote") || // see below
              element.LowerCaseEqualsLiteral("ul") ||
              element.LowerCaseEqualsLiteral("ol") ||
              element.LowerCaseEqualsLiteral("li") ||
              element.LowerCaseEqualsLiteral("dl") ||
              element.LowerCaseEqualsLiteral("dt") ||
              element.LowerCaseEqualsLiteral("dd")
            )
    {
      *_retval = nsIMsgCompConvertible::Yes;
    }
    else if (
              //element.LowerCaseEqualsLiteral("a") || // see below
              element.LowerCaseEqualsLiteral("h1") ||
              element.LowerCaseEqualsLiteral("h2") ||
              element.LowerCaseEqualsLiteral("h3") ||
              element.LowerCaseEqualsLiteral("h4") ||
              element.LowerCaseEqualsLiteral("h5") ||
              element.LowerCaseEqualsLiteral("h6") ||
              element.LowerCaseEqualsLiteral("hr") ||
              (
                mConvertStructs
                &&
                (
                  element.LowerCaseEqualsLiteral("em") ||
                  element.LowerCaseEqualsLiteral("strong") ||
                  element.LowerCaseEqualsLiteral("code") ||
                  element.LowerCaseEqualsLiteral("b") ||
                  element.LowerCaseEqualsLiteral("i") ||
                  element.LowerCaseEqualsLiteral("u")
                )
              )
            )
    {
      *_retval = nsIMsgCompConvertible::Altering;
    }
    else if (element.LowerCaseEqualsLiteral("body"))
    {
      *_retval = nsIMsgCompConvertible::Plain;

      nsCOMPtr<nsIDOMElement> domElement = do_QueryInterface(node);
      if (domElement)
      {
        PRBool hasAttribute;
        nsAutoString color;
        if (NS_SUCCEEDED(domElement->HasAttribute(NS_LITERAL_STRING("background"), &hasAttribute))
            && hasAttribute)  // There is a background image
          *_retval = nsIMsgCompConvertible::No; 
        else if (NS_SUCCEEDED(domElement->HasAttribute(NS_LITERAL_STRING("text"), &hasAttribute)) &&
                 hasAttribute &&
                 NS_SUCCEEDED(domElement->GetAttribute(NS_LITERAL_STRING("text"), color)) &&
                 !color.EqualsLiteral("#000000")) {
          *_retval = nsIMsgCompConvertible::Altering;
        }
        else if (NS_SUCCEEDED(domElement->HasAttribute(NS_LITERAL_STRING("bgcolor"), &hasAttribute)) &&
                 hasAttribute &&
                 NS_SUCCEEDED(domElement->GetAttribute(NS_LITERAL_STRING("bgcolor"), color)) &&
                 !color.LowerCaseEqualsLiteral("#ffffff")) {
          *_retval = nsIMsgCompConvertible::Altering;
        }
              else if (NS_SUCCEEDED(domElement->HasAttribute(NS_LITERAL_STRING("dir"), &hasAttribute))
            && hasAttribute)  // dir=rtl attributes should not downconvert
          *_retval = nsIMsgCompConvertible::No; 

        //ignore special color setting for link, vlink and alink at this point.
      }

    }
    else if (element.LowerCaseEqualsLiteral("blockquote"))
    {
      // Skip <blockquote type="cite">
      *_retval = nsIMsgCompConvertible::Yes;

      nsCOMPtr<nsIDOMNamedNodeMap> pAttributes;
      if (NS_SUCCEEDED(node->GetAttributes(getter_AddRefs(pAttributes)))
          && pAttributes)
      {
        nsAutoString typeName; typeName.AssignLiteral("type");
        if (NS_SUCCEEDED(pAttributes->GetNamedItem(typeName,
                                                   getter_AddRefs(pItem)))
            && pItem)
        {
          nsAutoString typeValue;
          if (NS_SUCCEEDED(pItem->GetNodeValue(typeValue)))
          {
            typeValue.StripChars("\"");
            if (typeValue.LowerCaseEqualsLiteral("cite"))
              *_retval = nsIMsgCompConvertible::Plain;
          }
        }
      }
    }
    else if (
              element.LowerCaseEqualsLiteral("div") ||
              element.LowerCaseEqualsLiteral("span") ||
              element.LowerCaseEqualsLiteral("a")
            )
    {
      /* Do some special checks for these tags. They are inside this |else if|
         for performance reasons */
      nsCOMPtr<nsIDOMNamedNodeMap> pAttributes;

      /* First, test, if the <a>, <div> or <span> is inserted by our
         [TXT|HTML]->HTML converter */
      /* This is for an edge case: A Mozilla user replies to plaintext per HTML
         and the recipient of that HTML msg, also a Mozilla user, replies to
         that again. Then we'll have to recognize the stuff inserted by our
         TXT->HTML converter. */
      if (NS_SUCCEEDED(node->GetAttributes(getter_AddRefs(pAttributes)))
          && pAttributes)
      {
        nsAutoString className;
        className.AssignLiteral("class");
        if (NS_SUCCEEDED(pAttributes->GetNamedItem(className,
                                                   getter_AddRefs(pItem)))
            && pItem)
        {
          nsAutoString classValue;
          if (NS_SUCCEEDED(pItem->GetNodeValue(classValue))
              && (classValue.EqualsIgnoreCase("moz-txt", 7) ||
                  classValue.EqualsIgnoreCase("\"moz-txt", 8)))
          {
            *_retval = nsIMsgCompConvertible::Plain;
            return rv;  // Inconsistent :-(
          }
        }
      }

      // Maybe, it's an <a> element inserted by another recognizer (e.g. 4.x')
      if (element.LowerCaseEqualsLiteral("a"))
      {
        /* Ignore anchor tag, if the URI is the same as the text
           (as inserted by recognizers) */
        *_retval = nsIMsgCompConvertible::Altering;

        if (NS_SUCCEEDED(node->GetAttributes(getter_AddRefs(pAttributes)))
            && pAttributes)
        {
          nsAutoString hrefName; hrefName.AssignLiteral("href");
          if (NS_SUCCEEDED(pAttributes->GetNamedItem(hrefName,
                                                     getter_AddRefs(pItem)))
              && pItem)
          {
            nsAutoString hrefValue;
            PRBool hasChild;
            if (NS_SUCCEEDED(pItem->GetNodeValue(hrefValue))
                && NS_SUCCEEDED(node->HasChildNodes(&hasChild)) && hasChild)
            {
              nsCOMPtr<nsIDOMNodeList> children;
              if (NS_SUCCEEDED(node->GetChildNodes(getter_AddRefs(children)))
                  && children
                  && NS_SUCCEEDED(children->Item(0, getter_AddRefs(pItem)))
                  && pItem)
              {
                nsAutoString textValue;
                if (NS_SUCCEEDED(pItem->GetNodeValue(textValue))
                    && textValue == hrefValue)
                  *_retval = nsIMsgCompConvertible::Plain;
              }
            }
          }
        }
      }

      // Lastly, test, if it is just a "simple" <div> or <span>
      else if (
                element.LowerCaseEqualsLiteral("div") ||
                element.LowerCaseEqualsLiteral("span")
              )
      {
        /* skip only if no style attribute */
        *_retval = nsIMsgCompConvertible::Plain;

        if (NS_SUCCEEDED(node->GetAttributes(getter_AddRefs(pAttributes)))
            && pAttributes)
        {
          nsAutoString styleName;
          styleName.AssignLiteral("style");
          if (NS_SUCCEEDED(pAttributes->GetNamedItem(styleName,
                                                     getter_AddRefs(pItem)))
              && pItem)
          {
            nsAutoString styleValue;
            if (NS_SUCCEEDED(pItem->GetNodeValue(styleValue))
                && !styleValue.IsEmpty())
              *_retval = nsIMsgCompConvertible::No;
          }
        }
      }
    }

    return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 470 of file nsMsgCompose.cpp.

{
  nsresult rv = NS_OK;
  nsCOMPtr<nsISupportsArray> aNodeList;
  PRUint32 count;
  PRUint32 i;

  if (!aEditor)
    return NS_ERROR_FAILURE;

  rv = aEditor->GetEmbeddedObjects(getter_AddRefs(aNodeList));
  if ((NS_FAILED(rv) || (!aNodeList)))
    return NS_ERROR_FAILURE;

  if (NS_FAILED(aNodeList->Count(&count)))
    return NS_ERROR_FAILURE;

  nsCOMPtr<nsIDOMNode> node;

  nsCOMPtr<nsIURI> originalUrl;
  nsXPIDLCString originalScheme;
  nsXPIDLCString originalHost;
  nsXPIDLCString originalPath;

  // first, convert the rdf original msg uri into a url that represents the message...
  nsCOMPtr <nsIMsgMessageService> msgService;
  rv = GetMessageServiceFromURI(mOriginalMsgURI.get(), getter_AddRefs(msgService));
  if (NS_SUCCEEDED(rv))
  {
    rv = msgService->GetUrlForUri(mOriginalMsgURI.get(), getter_AddRefs(originalUrl), nsnull);
    if (NS_SUCCEEDED(rv) && originalUrl)
    {
      originalUrl->GetScheme(originalScheme);
      originalUrl->GetAsciiHost(originalHost);
      originalUrl->GetPath(originalPath);
    }
  }

  // Then compare the url of each embedded objects with the original message.
  // If they a not coming from the original message, they should not be sent
  // with the message.
  nsCOMPtr<nsIDOMElement> domElement;
  for (i = 0; i < count; i ++)
  {
    node = do_QueryElementAt(aNodeList, i);
    if (!node)
      continue;
    if (IsEmbeddedObjectSafe(originalScheme.get(), originalHost.get(),
                             originalPath.get(), node))
      continue; //Don't need to tag this object, it safe to send it.

    //The source of this object should not be sent with the message 
    domElement = do_QueryInterface(node);
    if (domElement)
      domElement->SetAttribute(NS_LITERAL_STRING("moz-do-not-send"), NS_LITERAL_STRING("true"));
  }

  return NS_OK;
}

Here is the call graph for this function:


Friends And Related Function Documentation

friend class nsMsgComposeSendListener [friend]

Definition at line 171 of file nsMsgCompose.h.

friend class QuotingOutputStreamListener [friend]

Definition at line 170 of file nsMsgCompose.h.


Member Data Documentation

Definition at line 217 of file nsIMsgCompose.idl.

Definition at line 202 of file nsIMsgCompose.idl.

Definition at line 205 of file nsIMsgCompose.idl.

Definition at line 282 of file nsIMsgCompose.idl.

Definition at line 199 of file nsIMsgCompose.idl.

Definition at line 196 of file nsIMsgCompose.idl.

Definition at line 287 of file nsIMsgCompose.idl.

Definition at line 142 of file nsMsgCompose.h.

Definition at line 143 of file nsMsgCompose.h.

Definition at line 145 of file nsMsgCompose.h.

Definition at line 140 of file nsMsgCompose.h.

Definition at line 120 of file nsMsgCompose.h.

Definition at line 144 of file nsMsgCompose.h.

Definition at line 141 of file nsMsgCompose.h.

Definition at line 147 of file nsMsgCompose.h.

Definition at line 160 of file nsMsgCompose.h.

Definition at line 155 of file nsMsgCompose.h.

Definition at line 138 of file nsMsgCompose.h.

Definition at line 161 of file nsMsgCompose.h.

Definition at line 162 of file nsMsgCompose.h.

Definition at line 193 of file nsIMsgCompose.idl.

Definition at line 165 of file nsMsgCompose.h.

Definition at line 168 of file nsMsgCompose.h.

Definition at line 151 of file nsMsgCompose.h.

Definition at line 97 of file nsMsgCompose.h.

Definition at line 163 of file nsMsgCompose.h.

Definition at line 152 of file nsMsgCompose.h.

Definition at line 156 of file nsMsgCompose.h.

Definition at line 96 of file nsMsgCompose.h.

Definition at line 146 of file nsMsgCompose.h.

Definition at line 157 of file nsMsgCompose.h.

Definition at line 150 of file nsMsgCompose.h.

Definition at line 149 of file nsMsgCompose.h.

Definition at line 166 of file nsMsgCompose.h.

Definition at line 159 of file nsMsgCompose.h.

Definition at line 158 of file nsMsgCompose.h.

Definition at line 99 of file nsMsgCompose.h.

Definition at line 280 of file nsIMsgCompose.idl.

Definition at line 260 of file nsIMsgCompose.idl.

Definition at line 278 of file nsIMsgCompose.idl.

Definition at line 275 of file nsIMsgCompose.idl.

Definition at line 238 of file nsIMsgCompose.idl.

Definition at line 208 of file nsIMsgCompose.idl.

Definition at line 211 of file nsIMsgCompose.idl.


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