home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / winfe / mapimail.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  23.7 KB  |  835 lines

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18. //
  19. //  More MAPI Hooks for Communicator
  20. //  Written by: Rich Pizzarro (rhp@netscape.com)
  21. //  November 1997
  22. //
  23. #include "stdafx.h"
  24. #include "template.h"
  25. #include "msgcom.h"
  26. #include "wfemsg.h"
  27. #include "compstd.h"
  28. #include "compbar.h"
  29. #include "compmisc.h"
  30. #include "compfrm.h"
  31. #include "prefapi.h"
  32. #include "intl_csi.h"
  33. #include "dlghtmrp.h"
  34. #include "dlghtmmq.h"
  35.  
  36. // rhp - was breaking the optimized build!
  37. //#include "edt.h"
  38. //#include "edview.h"
  39. //#include "postal.h"
  40. //#include "apiaddr.h"
  41. //#include "mailmisc.h"
  42.  
  43. extern "C" {
  44. #include "xpgetstr.h"
  45. extern int MK_MSG_MSG_COMPOSITION;
  46. };
  47.  
  48. #include "mapimail.h"
  49. #include "nscpmapi.h"
  50. #include "mailpriv.h"
  51. #include "nsstrseq.h"
  52.  
  53. MWContext             
  54. *GetUsableContext(void)
  55. {
  56.   CGenericFrame     *pFrame = (CGenericFrame * )FEU_GetLastActiveFrame();
  57.  
  58.   ASSERT(pFrame != NULL);
  59.   if (pFrame == NULL)
  60.   {
  61.     return(NULL);
  62.   }
  63.  
  64.   // Now return the context...
  65.   return((MWContext *) pFrame->GetMainContext());
  66. }
  67.  
  68. //
  69. // This function will create a composition window and either do
  70. // a blind send or pop up the compose window for the user to 
  71. // complete the operation
  72. //
  73. // Return: appropriate MAPI return code...
  74. //
  75. // 
  76. extern "C" LONG
  77. DoFullMAPIMailOperation(MAPISendMailType      *sendMailPtr,
  78.                                               const char            *pInitialText,
  79.                         BOOL                  winShowFlag)
  80. {   
  81. CGenericDoc             *pDocument;
  82. LPSTR                   subject;
  83. NSstringSeq             mailInfoSeq;
  84. DWORD                   stringCount = 6;
  85. DWORD                   i;
  86. CString                 csDefault;
  87.  
  88.   // Get a context to use for this call...
  89.   MWContext *pOldContext = GetUsableContext();
  90.   if (!pOldContext)
  91.   {
  92.     return(MAPI_E_FAILURE);
  93.   }
  94.  
  95.   // Don't allow a compose window to be created if the user hasn't 
  96.   // specified an email address
  97.   const char *real_addr = FE_UsersMailAddress();
  98.   if (MISC_ValidateReturnAddress(pOldContext, real_addr) < 0)
  99.   {
  100.     return(MAPI_E_FAILURE);
  101.   }
  102.  
  103.   //
  104.   // Now, we must build the fields object...
  105.   //
  106.   mailInfoSeq = (NSstringSeq) &(sendMailPtr->dataBuf[0]);
  107.   subject = NSStrSeqGet(mailInfoSeq, 0);
  108.  
  109.   // We should give it a subject to preven the prompt from coming
  110.   // up...
  111.   if ((!subject) || !(*subject))
  112.   {
  113.     csDefault.LoadString(IDS_COMPOSE_DEFAULTNOSUBJECT);
  114.     subject = csDefault.GetBuffer(2);
  115.   }
  116.  
  117.   TRACE("MAPI: ProcessMAPISendMail() Subject   = [%s]\n", subject);
  118.   TRACE("MAPI: ProcessMAPISendMail() Text Size = [%d]\n", strlen((const char *)pInitialText));
  119.   TRACE("MAPI: ProcessMAPISendMail() # of Recipients  = [%d]\n", sendMailPtr->MSG_nRecipCount);
  120.  
  121.  
  122.   char  toString[1024] = "";
  123.   char  ccString[1024] = "";
  124.   char  bccString[1024] = "";
  125.  
  126.   for (i=0; i<sendMailPtr->MSG_nRecipCount; i++)
  127.   {
  128.     LPSTR   ptr;
  129.     UCHAR   tempString[256];
  130.  
  131.     ULONG addrType = atoi(NSStrSeqGet(mailInfoSeq, stringCount++));
  132.  
  133.     // figure which type of address this is?
  134.     if (addrType == MAPI_CC)
  135.       ptr = ccString;
  136.     else if (addrType == MAPI_BCC)
  137.       ptr = bccString;
  138.     else
  139.       ptr = toString;
  140.       
  141.     LPSTR namePtr = (LPSTR) NSStrSeqGet(mailInfoSeq, stringCount++);
  142.     LPSTR emailPtr = (LPSTR) NSStrSeqGet(mailInfoSeq, stringCount++);
  143.     if ( (lstrlen(emailPtr) > 5) && (*(emailPtr + 4) == ':') )
  144.     {
  145.       emailPtr += 5;
  146.     }
  147.  
  148.     // Now build the temp string to tack on in the format
  149.     // "Rich Pizzarro" <rhp@netscape.com>
  150.     wsprintf((LPSTR) tempString, "\"%s\" <%s>", namePtr, emailPtr);
  151.  
  152.     // add a comma if not the first one
  153.     if (ptr[0] != '\0')
  154.       lstrcat(ptr, ",");
  155.  
  156.     // tack on string!
  157.     lstrcat(ptr, (LPSTR) tempString);
  158.   }
  159.  
  160.   BOOL    bEncrypt = FALSE;
  161.   BOOL    bSign    = FALSE;
  162.  
  163.   PREF_GetBoolPref("mail.crypto_sign_outgoing_mail", &bSign);
  164.   PREF_GetBoolPref("mail.encrypt_outgoing_mail", &bEncrypt);
  165.   MSG_CompositionFields *fields =
  166.       MSG_CreateCompositionFields(real_addr, real_addr, 
  167.                   toString, 
  168.                   ccString, 
  169.                   bccString,
  170.                                     "", "", "",
  171.                                     "", subject, "",
  172.                                     "", "", "",
  173.                                     "", 
  174.                   bEncrypt,
  175.                   bSign);
  176.   if (!fields)
  177.   {
  178.     return(MAPI_E_FAILURE);
  179.   }
  180.  
  181.   // RICHIE
  182.   // INTL_CharSetInfo csi = LO_GetDocumentCharacterSetInfo(pOldContext);
  183.   // int16 win_csid = INTL_GetCSIWinCSID(csi);
  184.   
  185.   pDocument = (CGenericDoc*)theApp.m_TextComposeTemplate->OpenDocumentFile(NULL, NULL, /*win_csid RICHIE*/ winShowFlag);
  186.   if ( !pDocument )
  187.   {
  188.     return(MAPI_E_FAILURE);
  189.   }
  190.   
  191.   CWinCX * pContext = (CWinCX*) pDocument->GetContext();
  192.   if ( !pContext ) 
  193.   {
  194.     return(MAPI_E_FAILURE);
  195.   }
  196.  
  197.   MSG_CompositionPaneCallbacks Callbacks;
  198.   Callbacks.CreateRecipientsDialog = CreateRecipientsDialog;
  199.   Callbacks.CreateAskHTMLDialog = CreateAskHTMLDialog;
  200.  
  201.   int16 doccsid;
  202.   MWContext *context = pContext->GetContext();
  203.   CComposeFrame *pCompose = (CComposeFrame *) pContext->GetFrame()->GetFrameWnd();
  204.  
  205.   pCompose->SetComposeStuff(context, fields); // squirl away stuff for post-create
  206.  
  207.   // This needs to be set TRUE if using the old non-HTML text frame
  208.   // to prevent dropping dragged URLs
  209.   pContext->m_bDragging = !pCompose->UseHtml();
  210.   if (!pCompose->UseHtml()) 
  211.   {
  212.     pCompose->SetMsgPane(
  213.       MSG_CreateCompositionPane(pContext->GetContext(), 
  214.                                 context, 
  215.                                 g_MsgPrefs.m_pMsgPrefs, 
  216.                                 fields,
  217.                                 WFE_MSGGetMaster())
  218.                         );
  219.   }
  220.  
  221.   ASSERT(pCompose->GetMsgPane());
  222.   MSG_SetFEData(pCompose->GetMsgPane(),(void *)pCompose);  
  223.   pCompose->UpdateAttachmentInfo();
  224.  
  225.   // Pass doccsid info to new context for MailToWin conversion
  226.   doccsid = INTL_GetCSIDocCSID(LO_GetDocumentCharacterSetInfo(context));
  227.   INTL_SetCSIDocCSID(LO_GetDocumentCharacterSetInfo(context), 
  228.     (doccsid ? doccsid : INTL_DefaultDocCharSetID(context)));
  229.  
  230.   pCompose->DisplayHeaders(NULL);
  231.  
  232.   CComposeBar * pBar = pCompose->GetComposeBar();
  233.   ASSERT(pBar);
  234.   LPADDRESSCONTROL pIAddressList = pBar->GetAddressWidgetInterface();
  235.  
  236.   if (!pIAddressList->IsCreated()) 
  237.   {
  238.     pBar->CreateAddressingBlock();
  239.   }
  240.  
  241.   // rhp - Deal with addressing the brute force way! This is a 
  242.   // "fix" for bad behavior when creating these windows and not
  243.   // showing them on the desktop.
  244.   if (!winShowFlag)      // Hack to fix the window not being mapped
  245.   {
  246.     pCompose->AppendAddress(MSG_TO_HEADER_MASK, "");
  247.     pCompose->AppendAddress(MSG_CC_HEADER_MASK, "");
  248.     pCompose->AppendAddress(MSG_BCC_HEADER_MASK, "");
  249.   }
  250.  
  251.   // Always do plain text composition!
  252.   pCompose->CompleteComposeInitialization();
  253.  
  254.   // Do this so we don't get popups on "empty" messages
  255.   if ( (!pInitialText) || (!(*pInitialText)) )
  256.     pInitialText = " ";
  257.  
  258.   const char * pBody = pInitialText ? pInitialText : MSG_GetCompBody(pCompose->GetMsgPane());
  259.   if (pBody)
  260.   {
  261.     FE_InsertMessageCompositionText(context,pBody,TRUE);
  262.   }
  263.  
  264.   // 
  265.   // Now set the message as being edited!    
  266.   //
  267.   pCompose->SetModified(TRUE);
  268.  
  269.   //
  270.   // Finally deal with the attachments...
  271.   //
  272.   if (sendMailPtr->MSG_nFileCount > 0)
  273.   {
  274.     // Send this puppy when done with the attachments...
  275.     if (!winShowFlag)
  276.     {
  277.       pCompose->SetMAPISendMode(MAPI_SEND);
  278.     }
  279.  
  280.     MSG_AttachmentData *pAttach = (MSG_AttachmentData *)
  281.                   XP_CALLOC((sendMailPtr->MSG_nFileCount + 1),
  282.                   sizeof(MSG_AttachmentData));
  283.     if (!pAttach)
  284.     {
  285.       return(MAPI_E_INSUFFICIENT_MEMORY);
  286.     }
  287.  
  288.     memset(pAttach, 0, (sendMailPtr->MSG_nFileCount + 1) * 
  289.                                 sizeof(MSG_AttachmentData));
  290.     for (i=0; i<sendMailPtr->MSG_nFileCount; i++)
  291.     {
  292.       CString cs;
  293.       // Create URL from filename...
  294.       WFE_ConvertFile2Url(cs, 
  295.           (const char *)NSStrSeqGet(mailInfoSeq, stringCount++));
  296.       pAttach[i].url = XP_STRDUP(cs);
  297.  
  298.       // Now also include the "display" name...
  299.       StrAllocCopy(pAttach[i].real_name, NSStrSeqGet(mailInfoSeq, stringCount++));
  300.     }
  301.  
  302.     // Set the list!
  303.     MSG_SetAttachmentList(pCompose->GetMsgPane(), pAttach);
  304.  
  305.     // Now free everything...
  306.     for (i=0; i<sendMailPtr->MSG_nFileCount; i++)
  307.     {
  308.       if (pAttach[i].url)
  309.         XP_FREE(pAttach[i].url);
  310.  
  311.       if (pAttach[i].real_name)
  312.         XP_FREE(pAttach[i].real_name);
  313.     }
  314.  
  315.     XP_FREE(pAttach);
  316.   }
  317.  
  318.   //
  319.   // Now, if we were supposed to do the blind send...do it, otherwise,
  320.   // just popup the window...
  321.   //
  322.   if (winShowFlag)      
  323.   {
  324.     // Post message to compose window to set the initial focus.
  325.     pCompose->PostMessage(WM_COMP_SET_INITIAL_FOCUS);
  326.   }
  327.   else if (sendMailPtr->MSG_nFileCount <= 0)  // Send NOW if no attachments!
  328.   {
  329.     pCompose->PostMessage(WM_COMMAND, IDM_SEND);
  330.   }
  331.  
  332.   return(SUCCESS_SUCCESS);
  333. }
  334.  
  335. //
  336. // This function will create a composition window and just attach
  337. // the attachments of interest and pop up the window...
  338. //
  339. // Return: appropriate MAPI return code...
  340. //
  341. //
  342. extern "C" LONG
  343. DoPartialMAPIMailOperation(MAPISendDocumentsType *sendDocPtr)
  344. {   
  345. CGenericDoc             *pDocument;
  346.  
  347.   // Get a context to use for this call...
  348.   MWContext *pOldContext = GetUsableContext();
  349.   if (!pOldContext)
  350.   {
  351.     return(MAPI_E_FAILURE);
  352.   }
  353.  
  354.   // Don't allow a compose window to be created if the user hasn't 
  355.   // specified an email address
  356.   const char *real_addr = FE_UsersMailAddress();
  357.   if (MISC_ValidateReturnAddress(pOldContext, real_addr) < 0)
  358.   {
  359.     return(MAPI_E_FAILURE);
  360.   }
  361.  
  362.   //
  363.   // Now, build the fields object w/o much info...
  364.   //
  365.   BOOL    bEncrypt = FALSE;
  366.   BOOL    bSign    = FALSE;
  367.  
  368.   PREF_GetBoolPref("mail.crypto_sign_outgoing_mail", &bSign);
  369.   PREF_GetBoolPref("mail.encrypt_outgoing_mail", &bEncrypt);
  370.  
  371.   MSG_CompositionFields *fields =
  372.       MSG_CreateCompositionFields(real_addr, real_addr, NULL, 
  373.                   "", "",
  374.                                     "", "", "",
  375.                                     "", "", "",
  376.                                     "", "", "",
  377.                                     "", 
  378.                   bEncrypt,
  379.                   bSign);
  380.   if (!fields)
  381.   {
  382.     return(MAPI_E_FAILURE);
  383.   }
  384.  
  385.   // RICHIE - INTL_CharSetInfo csi = LO_GetDocumentCharacterSetInfo(pOldContext);
  386.   // int16 win_csid = INTL_GetCSIWinCSID(csi);
  387.  
  388.   pDocument = (CGenericDoc*)theApp.m_TextComposeTemplate->OpenDocumentFile(NULL, NULL, /*RICHIE win_csid,*/ TRUE);
  389.   if ( !pDocument )
  390.   {
  391.     // cleanup fields object
  392.     MSG_DestroyCompositionFields(fields);
  393.     return(MAPI_E_FAILURE);
  394.   }
  395.  
  396.   CWinCX * pContext = (CWinCX*) pDocument->GetContext();
  397.   if ( !pContext ) 
  398.   {
  399.     return(MAPI_E_FAILURE);
  400.   }
  401.  
  402.   MSG_CompositionPaneCallbacks Callbacks;
  403.   Callbacks.CreateRecipientsDialog = CreateRecipientsDialog;
  404.   Callbacks.CreateAskHTMLDialog = CreateAskHTMLDialog;
  405.  
  406.   MWContext *context = pContext->GetContext();
  407.   CComposeFrame *pCompose = (CComposeFrame *) pContext->GetFrame()->GetFrameWnd();
  408.   pCompose->SetComposeStuff(context,fields); // squirl away stuff for post-create
  409.  
  410.   // This needs to be set TRUE if using the old non-HTML text frame
  411.   // to prevent dropping dragged URLs
  412.   pContext->m_bDragging = !pCompose->UseHtml();
  413.   if (!pCompose->UseHtml()) 
  414.   {
  415.     pCompose->SetMsgPane(MSG_CreateCompositionPane(
  416.       pContext->GetContext(), 
  417.       context,
  418.       g_MsgPrefs.m_pMsgPrefs, fields,
  419.       WFE_MSGGetMaster()));
  420.   }
  421.  
  422.   ASSERT(pCompose->GetMsgPane());
  423.   MSG_SetFEData(pCompose->GetMsgPane(),(void *)pCompose);
  424.  
  425.   pCompose->UpdateAttachmentInfo();
  426.  
  427.   // Pass doccsid info to new context for MailToWin conversion
  428.   /***
  429.   doccsid = INTL_GetCSIDocCSID(LO_GetDocumentCharacterSetInfo(pOldContext));
  430.  
  431.   INTL_SetCSIDocCSID(LO_GetDocumentCharacterSetInfo(context), 
  432.     (doccsid ? doccsid : INTL_DefaultDocCharSetID(pOldContext)));
  433.   ****/
  434.  
  435.   pCompose->DisplayHeaders(NULL);
  436.  
  437.   CComposeBar * pBar = pCompose->GetComposeBar();
  438.   ASSERT(pBar);
  439.   LPADDRESSCONTROL pIAddressList = pBar->GetAddressWidgetInterface();
  440.  
  441.   if (!pIAddressList->IsCreated()) 
  442.   {
  443.     pBar->CreateAddressingBlock();
  444.   }
  445.  
  446.   // Always do plain text composition!
  447.   pCompose->CompleteComposeInitialization();
  448.  
  449.   //
  450.   // Finally deal with the attachments...
  451.   //
  452.   NSstringSeq     mailInfoSeq = (NSstringSeq) &(sendDocPtr->dataBuf[0]);
  453.   DWORD           stringCount = 0;
  454.   DWORD           i;
  455.  
  456.   TRACE("MAPI: ProcessMAPISendDocuments() # of Attachments = [%d]\n", sendDocPtr->nFileCount);
  457.  
  458.   if (sendDocPtr->nFileCount > 0)
  459.   {
  460.       MSG_AttachmentData *pAttach = (MSG_AttachmentData *)
  461.                     XP_CALLOC((sendDocPtr->nFileCount + 1),
  462.                     sizeof(MSG_AttachmentData));
  463.       if (!pAttach)
  464.       {
  465.         return(MAPI_E_INSUFFICIENT_MEMORY);
  466.       }
  467.  
  468.       memset(pAttach, 0, (sendDocPtr->nFileCount + 1) * 
  469.                                   sizeof(MSG_AttachmentData));
  470.       for (i=0; i<sendDocPtr->nFileCount; i++)
  471.       {
  472.         CString cs;
  473.         // Create URL from filename...
  474.         WFE_ConvertFile2Url(cs, 
  475.             (const char *)NSStrSeqGet(mailInfoSeq, stringCount++));
  476.         pAttach[i].url = XP_STRDUP(cs);
  477.  
  478.         // Now also include the "display" name...
  479.         StrAllocCopy(pAttach[i].real_name, NSStrSeqGet(mailInfoSeq, stringCount++));
  480.       }
  481.  
  482.       // Set the list!
  483.       MSG_SetAttachmentList(pCompose->GetMsgPane(), pAttach);
  484.  
  485.       // Now free everything...
  486.       for (i=0; i<sendDocPtr->nFileCount; i++)
  487.       {
  488.         if (pAttach[i].url)
  489.           XP_FREE(pAttach[i].url);
  490.  
  491.         if (pAttach[i].real_name)
  492.           XP_FREE(pAttach[i].real_name);
  493.       }
  494.  
  495.       XP_FREE(pAttach);
  496.   }
  497.     
  498.   // 
  499.   // Now some checking for ... well I'm not sure...
  500.   //
  501.   if (MSG_GetAttachmentList(pCompose->GetMsgPane()))
  502.     pCompose->SetModified(TRUE);
  503.   else
  504.     pCompose->SetModified(FALSE);
  505.  
  506.   // Post message to compose window to set the initial focus.
  507.   pCompose->PostMessage(WM_COMP_SET_INITIAL_FOCUS);
  508.  
  509.   //
  510.   // Now, just popup the window...
  511.   //
  512.   pCompose->ShowWindow(TRUE);
  513.  
  514.   // return pCompose->GetMsgPane(); rhp - used to return the MsgPane
  515.   return(SUCCESS_SUCCESS);
  516. }
  517.  
  518. static void _GetMailCallback(HWND hwnd, MSG_Pane *pane, void *closure)
  519. {
  520.    if (pane != NULL)
  521.    {
  522.      ShowWindow(hwnd, SW_HIDE);
  523.      MSG_Command( pane, MSG_GetNewMail, NULL, 0 );
  524.    }
  525. }
  526.  
  527. static void _GetMailDoneCallback(HWND hwnd, MSG_Pane *pane, void *closure)
  528. {
  529.     for(CGenericFrame * f = theApp.m_pFrameList; f; f = f->m_pNext)
  530.         f->PostMessage(WM_COMMAND, (WPARAM) ID_DONEGETTINGMAIL, (LPARAM) 0);
  531. }
  532.  
  533. //
  534. // This will fire off a "get mail in background operation" in an
  535. // async. fashion.
  536. //
  537. extern "C" void
  538. MAPIGetNewMessagesInBackground(void)
  539. {
  540. CGenericFrame     *pFrame = (CGenericFrame * )FEU_GetLastActiveFrame();
  541.  
  542.   // rhp - we should not hit the net if we are offline!
  543.   if (NET_IsOffline())
  544.     return;
  545.  
  546.   if (!pFrame)
  547.     return;
  548.  
  549.   MWContext *pOldContext = GetUsableContext();
  550.   if (!pOldContext)
  551.     return;
  552.  
  553.   TRACE("MAPI: DOWNLOAD MAIL IN BACKGROUND\n");
  554.   new CProgressDialog(
  555.                 pFrame->GetFrameWnd(), 
  556.                 NULL, 
  557.                 _GetMailCallback, NULL, NULL, 
  558.                 _GetMailDoneCallback);
  559. }
  560.  
  561. //
  562. // This function will save a message into the Communicator "Drafts"
  563. // folder with no UI showing.
  564. //
  565. // Return: appropriate MAPI return code...
  566. //
  567. //
  568. extern "C" LONG 
  569. DoMAPISaveMailOperation(MAPISendMailType      *sendMailPtr,
  570.                                               const char            *pInitialText)
  571. {
  572. CGenericDoc             *pDocument;
  573. LPSTR                   subject;
  574. NSstringSeq             mailInfoSeq;
  575. DWORD                   stringCount = 6;
  576. DWORD                   i;
  577. BOOL                    winShowFlag = FALSE;
  578.  
  579.   // Get a context to use for this call...
  580.   MWContext *pOldContext = GetUsableContext();
  581.   if (!pOldContext)
  582.   {
  583.     return(MAPI_E_FAILURE);
  584.   }
  585.  
  586.   // Don't allow a compose window to be created if the user hasn't 
  587.   // specified an email address
  588.   const char *real_addr = FE_UsersMailAddress();
  589.   if (MISC_ValidateReturnAddress(pOldContext, real_addr) < 0)
  590.   {
  591.     return(MAPI_E_FAILURE);
  592.   }
  593.  
  594.   //
  595.   // Now, we must build the fields object...
  596.   //
  597.   mailInfoSeq = (NSstringSeq) &(sendMailPtr->dataBuf[0]);
  598.   subject = NSStrSeqGet(mailInfoSeq, 0);
  599.  
  600.   TRACE("MAPI: ProcessMAPISendMail() Subject   = [%s]\n", subject);
  601.   TRACE("MAPI: ProcessMAPISendMail() Text Size = [%d]\n", strlen((const char *)pInitialText));
  602.   TRACE("MAPI: ProcessMAPISendMail() # of Recipients  = [%d]\n", sendMailPtr->MSG_nRecipCount);
  603.  
  604.  
  605.   char  toString[1024] = "";
  606.   char  ccString[1024] = "";
  607.   char  bccString[1024] = "";
  608.  
  609.   for (i=0; i<sendMailPtr->MSG_nRecipCount; i++)
  610.   {
  611.     LPSTR   ptr;
  612.     UCHAR   tempString[256];
  613.  
  614.     ULONG addrType = atoi(NSStrSeqGet(mailInfoSeq, stringCount++));
  615.  
  616.     // figure which type of address this is?
  617.     if (addrType == MAPI_CC)
  618.       ptr = ccString;
  619.     else if (addrType == MAPI_BCC)
  620.       ptr = bccString;
  621.     else
  622.       ptr = toString;
  623.  
  624.     LPSTR namePtr = (LPSTR) NSStrSeqGet(mailInfoSeq, stringCount++);
  625.     LPSTR emailPtr = (LPSTR) NSStrSeqGet(mailInfoSeq, stringCount++);
  626.  
  627.     if ( (!emailPtr) && (!namePtr))
  628.     {
  629.       return(MAPI_E_INVALID_RECIPS);
  630.     }
  631.  
  632.     if (!emailPtr)
  633.       emailPtr = namePtr;
  634.  
  635.     char *tptr = strchr(emailPtr, ':');
  636.     if (tptr != NULL)
  637.     {
  638.       if ( (*tptr != '\0') && (*(tptr+1) != '\0') )
  639.       {
  640.         emailPtr = (tptr + 1);
  641.       }
  642.     }
  643. /**
  644.     if ( (lstrlen(emailPtr) > 5) && (*(emailPtr + 4) == ':') )
  645.     {
  646.       emailPtr += 5;
  647.     }
  648. **/
  649.     // Now build the temp string to tack on in the format
  650.     // "Rich Pizzarro" <rhp@netscape.com>
  651.     wsprintf((LPSTR) tempString, "\"%s\" <%s>", namePtr, emailPtr);
  652.  
  653.     // add a comma if not the first one
  654.     if (ptr[0] != '\0')
  655.       lstrcat(ptr, ",");
  656.  
  657.     // tack on string!
  658.     lstrcat(ptr, (LPSTR) tempString);
  659.   }
  660.  
  661.   BOOL    bEncrypt = FALSE;
  662.   BOOL    bSign    = FALSE;
  663.  
  664.   PREF_GetBoolPref("mail.crypto_sign_outgoing_mail", &bSign);
  665.   PREF_GetBoolPref("mail.encrypt_outgoing_mail", &bEncrypt);
  666.   MSG_CompositionFields *fields =
  667.       MSG_CreateCompositionFields(real_addr, real_addr, 
  668.                   toString, 
  669.                   ccString, 
  670.                   bccString,
  671.                                     "", "", "",
  672.                                     "", subject, "",
  673.                                     "", "", "",
  674.                                     "", 
  675.                   bEncrypt,
  676.                   bSign);
  677.   if (!fields)
  678.   {
  679.     return(MAPI_E_FAILURE);
  680.   }
  681.  
  682.   // RICHIE
  683.   // INTL_CharSetInfo csi = LO_GetDocumentCharacterSetInfo(pOldContext);
  684.   // int16 win_csid = INTL_GetCSIWinCSID(csi);
  685.   
  686.   pDocument = (CGenericDoc*)theApp.m_TextComposeTemplate->OpenDocumentFile(NULL, NULL, /*win_csid RICHIE*/ winShowFlag);
  687.   if ( !pDocument )
  688.   {
  689.     return(MAPI_E_FAILURE);
  690.   }
  691.   
  692.   CWinCX * pContext = (CWinCX*) pDocument->GetContext();
  693.   if ( !pContext ) 
  694.   {
  695.     return(MAPI_E_FAILURE);
  696.   }
  697.  
  698.   MSG_CompositionPaneCallbacks Callbacks;
  699.   Callbacks.CreateRecipientsDialog = CreateRecipientsDialog;
  700.   Callbacks.CreateAskHTMLDialog = CreateAskHTMLDialog;
  701.  
  702.   int16 doccsid;
  703.   MWContext *context = pContext->GetContext();
  704.   CComposeFrame *pCompose = (CComposeFrame *) pContext->GetFrame()->GetFrameWnd();
  705.  
  706.   pCompose->SetComposeStuff(context, fields); // squirl away stuff for post-create
  707.  
  708.   // This needs to be set TRUE if using the old non-HTML text frame
  709.   // to prevent dropping dragged URLs
  710.   pContext->m_bDragging = !pCompose->UseHtml();
  711.   if (!pCompose->UseHtml()) 
  712.   {
  713.     pCompose->SetMsgPane(
  714.       MSG_CreateCompositionPane(pContext->GetContext(), 
  715.                                 context, 
  716.                                 g_MsgPrefs.m_pMsgPrefs, 
  717.                                 fields,
  718.                                 WFE_MSGGetMaster())
  719.                         );
  720.   }
  721.  
  722.   ASSERT(pCompose->GetMsgPane());
  723.   MSG_SetFEData(pCompose->GetMsgPane(),(void *)pCompose);  
  724.   pCompose->UpdateAttachmentInfo();
  725.  
  726.   // Pass doccsid info to new context for MailToWin conversion
  727.   doccsid = INTL_GetCSIDocCSID(LO_GetDocumentCharacterSetInfo(context));
  728.   INTL_SetCSIDocCSID(LO_GetDocumentCharacterSetInfo(context), 
  729.     (doccsid ? doccsid : INTL_DefaultDocCharSetID(context)));
  730.  
  731.   pCompose->DisplayHeaders(NULL);
  732.  
  733.   CComposeBar * pBar = pCompose->GetComposeBar();
  734.   ASSERT(pBar);
  735.   LPADDRESSCONTROL pIAddressList = pBar->GetAddressWidgetInterface();
  736.  
  737.   if (!pIAddressList->IsCreated()) 
  738.   {
  739.     pBar->CreateAddressingBlock();
  740.   }
  741.  
  742.   // rhp - Deal with addressing the brute force way! This is a 
  743.   // "fix" for bad behavior when creating these windows and not
  744.   // showing them on the desktop.
  745.   if (!winShowFlag)      // Hack to fix the window not being mapped
  746.   {
  747.     pCompose->AppendAddress(MSG_TO_HEADER_MASK, "");
  748.     pCompose->AppendAddress(MSG_CC_HEADER_MASK, "");
  749.     pCompose->AppendAddress(MSG_BCC_HEADER_MASK, "");
  750.   }
  751.  
  752.   // Always do plain text composition!
  753.   pCompose->CompleteComposeInitialization();
  754.  
  755.   // Do this so we don't get popups on "empty" messages
  756.   if ( (!pInitialText) || (!(*pInitialText)) )
  757.     pInitialText = " ";
  758.  
  759.   const char * pBody = pInitialText ? pInitialText : MSG_GetCompBody(pCompose->GetMsgPane());
  760.   if (pBody)
  761.   {
  762.     FE_InsertMessageCompositionText(context,pBody,TRUE);
  763.   }
  764.  
  765.   // 
  766.   // Now set the message as being edited!    
  767.   //
  768.   pCompose->SetModified(TRUE);
  769.  
  770.   //
  771.   // Finally deal with the attachments...
  772.   //
  773.   if (sendMailPtr->MSG_nFileCount > 0)
  774.   {
  775.     // Send this puppy when done with the attachments...
  776.     if (!winShowFlag)
  777.     {
  778.       pCompose->SetMAPISendMode(MAPI_SAVE);
  779.     }
  780.  
  781.     MSG_AttachmentData *pAttach = (MSG_AttachmentData *)
  782.                   XP_CALLOC((sendMailPtr->MSG_nFileCount + 1),
  783.                   sizeof(MSG_AttachmentData));
  784.     if (!pAttach)
  785.     {
  786.       return(MAPI_E_INSUFFICIENT_MEMORY);
  787.     }
  788.  
  789.     memset(pAttach, 0, (sendMailPtr->MSG_nFileCount + 1) * 
  790.                                 sizeof(MSG_AttachmentData));
  791.     for (i=0; i<sendMailPtr->MSG_nFileCount; i++)
  792.     {
  793.       CString cs;
  794.       // Create URL from filename...
  795.       WFE_ConvertFile2Url(cs, 
  796.           (const char *)NSStrSeqGet(mailInfoSeq, stringCount++));
  797.       pAttach[i].url = XP_STRDUP(cs);
  798.  
  799.       // Now also include the "display" name...
  800.       StrAllocCopy(pAttach[i].real_name, NSStrSeqGet(mailInfoSeq, stringCount++));
  801.     }
  802.  
  803.     // Set the list!
  804.     MSG_SetAttachmentList(pCompose->GetMsgPane(), pAttach);
  805.  
  806.     // Now free everything...
  807.     for (i=0; i<sendMailPtr->MSG_nFileCount; i++)
  808.     {
  809.       if (pAttach[i].url)
  810.         XP_FREE(pAttach[i].url);
  811.  
  812.       if (pAttach[i].real_name)
  813.         XP_FREE(pAttach[i].real_name);
  814.     }
  815.  
  816.     XP_FREE(pAttach);
  817.   }
  818.  
  819.   //
  820.   // Now, if we were supposed to do the blind send...do it, otherwise,
  821.   // just popup the window...
  822.   //
  823.   if (winShowFlag)      
  824.   {
  825.     // Post message to compose window to set the initial focus.
  826.     pCompose->PostMessage(WM_COMP_SET_INITIAL_FOCUS);
  827.   }
  828.   else if (sendMailPtr->MSG_nFileCount <= 0)  // Send NOW if no attachments!
  829.   {
  830.     pCompose->PostMessage(WM_COMMAND, IDM_SAVEASDRAFT);
  831.   }
  832.  
  833.   return(SUCCESS_SUCCESS);
  834. }
  835.