Back to index

lightning-sunbird  0.9+nobinonly
mapimail.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 //
00038 //  More MAPI Hooks for Communicator
00039 //  Written by: Rich Pizzarro (rhp@netscape.com)
00040 //  November 1997
00041 //
00042 #include "windows.h"
00043 #include "template.h"
00044 #include "msgcom.h"
00045 #include "wfemsg.h"
00046 #include "compstd.h"
00047 #include "compbar.h"
00048 #include "compmisc.h"
00049 #include "compfrm.h"
00050 #include "prefapi.h"
00051 #include "intl_csi.h"
00052 #include "dlghtmrp.h"
00053 #include "dlghtmmq.h"
00054 
00055 // rhp - was breaking the optimized build!
00056 //#include "edt.h"
00057 //#include "edview.h"
00058 //#include "postal.h"
00059 //#include "apiaddr.h"
00060 //#include "mailmisc.h"
00061 
00062 extern "C" {
00063 #include "xpgetstr.h"
00064 extern int MK_MSG_MSG_COMPOSITION;
00065 };
00066 
00067 #include "mapimail.h"
00068 #include "nscpmapi.h"
00069 #include "mailpriv.h"
00070 #include "nsstrseq.h"
00071 
00072 MWContext             
00073 *GetUsableContext(void)
00074 {
00075   CGenericFrame     *pFrame = (CGenericFrame * )FEU_GetLastActiveFrame();
00076 
00077   ASSERT(pFrame != NULL);
00078   if (pFrame == NULL)
00079   {
00080     return(NULL);
00081   }
00082 
00083   // Now return the context...
00084   return((MWContext *) pFrame->GetMainContext());
00085 }
00086 
00087 //
00088 // This function will create a composition window and either do
00089 // a blind send or pop up the compose window for the user to 
00090 // complete the operation
00091 //
00092 // Return: appropriate MAPI return code...
00093 //
00094 // 
00095 extern "C" LONG
00096 DoFullMAPIMailOperation(MAPISendMailType      *sendMailPtr,
00097                                                                                const char            *pInitialText,
00098                         BOOL                  winShowFlag)
00099 {   
00100 CGenericDoc             *pDocument;
00101 LPSTR                   subject;
00102 NSstringSeq             mailInfoSeq;
00103 DWORD                   stringCount = 6;
00104 DWORD                   i;
00105 CString                 csDefault;
00106 
00107   // Get a context to use for this call...
00108   MWContext *pOldContext = GetUsableContext();
00109   if (!pOldContext)
00110   {
00111     return(MAPI_E_FAILURE);
00112   }
00113 
00114   // Don't allow a compose window to be created if the user hasn't 
00115   // specified an email address
00116   const char *real_addr = FE_UsersMailAddress();
00117   if (MISC_ValidateReturnAddress(pOldContext, real_addr) < 0)
00118   {
00119     return(MAPI_E_FAILURE);
00120   }
00121 
00122   //
00123   // Now, we must build the fields object...
00124   //
00125   mailInfoSeq = (NSstringSeq) &(sendMailPtr->dataBuf[0]);
00126   subject = NSStrSeqGet(mailInfoSeq, 0);
00127 
00128   // We should give it a subject to preven the prompt from coming
00129   // up...
00130   if ((!subject) || !(*subject))
00131   {
00132     csDefault.LoadString(IDS_COMPOSE_DEFAULTNOSUBJECT);
00133     subject = csDefault.GetBuffer(2);
00134   }
00135 
00136   TRACE("MAPI: ProcessMAPISendMail() Subject   = [%s]\n", subject);
00137   TRACE("MAPI: ProcessMAPISendMail() Text Size = [%d]\n", strlen((const char *)pInitialText));
00138   TRACE("MAPI: ProcessMAPISendMail() # of Recipients  = [%d]\n", sendMailPtr->MSG_nRecipCount);
00139 
00140 
00141   char  toString[1024] = "";
00142   char  ccString[1024] = "";
00143   char  bccString[1024] = "";
00144 
00145   for (i=0; i<sendMailPtr->MSG_nRecipCount; i++)
00146   {
00147     LPSTR   ptr;
00148     UCHAR   tempString[256];
00149 
00150     ULONG addrType = atoi(NSStrSeqGet(mailInfoSeq, stringCount++));
00151 
00152     // figure which type of address this is?
00153     if (addrType == MAPI_CC)
00154       ptr = ccString;
00155     else if (addrType == MAPI_BCC)
00156       ptr = bccString;
00157     else
00158       ptr = toString;
00159       
00160     LPSTR namePtr = (LPSTR) NSStrSeqGet(mailInfoSeq, stringCount++);
00161     LPSTR emailPtr = (LPSTR) NSStrSeqGet(mailInfoSeq, stringCount++);
00162     if ( (lstrlen(emailPtr) > 5) && (*(emailPtr + 4) == ':') )
00163     {
00164       emailPtr += 5;
00165     }
00166 
00167     // Now build the temp string to tack on in the format
00168     // "Rich Pizzarro" <rhp@netscape.com>
00169     wsprintf((LPSTR) tempString, "\"%s\" <%s>", namePtr, emailPtr);
00170 
00171     // add a comma if not the first one
00172     if (ptr[0] != '\0')
00173       lstrcat(ptr, ",");
00174 
00175     // tack on string!
00176     lstrcat(ptr, (LPSTR) tempString);
00177   }
00178 
00179   BOOL    bEncrypt = FALSE;
00180   BOOL    bSign    = FALSE;
00181 
00182   PREF_GetBoolPref("mail.crypto_sign_outgoing_mail", &bSign);
00183   PREF_GetBoolPref("mail.encrypt_outgoing_mail", &bEncrypt);
00184   MSG_CompositionFields *fields =
00185       MSG_CreateCompositionFields(real_addr, real_addr, 
00186                   toString, 
00187                   ccString, 
00188                   bccString,
00189                                                                "", "", "",
00190                                                                "", subject, "",
00191                                                                "", "", "",
00192                                                                "", 
00193                   bEncrypt,
00194                   bSign);
00195   if (!fields)
00196   {
00197     return(MAPI_E_FAILURE);
00198   }
00199 
00200   // RICHIE
00201   // INTL_CharSetInfo csi = LO_GetDocumentCharacterSetInfo(pOldContext);
00202   // int16 win_csid = INTL_GetCSIWinCSID(csi);
00203   
00204   pDocument = (CGenericDoc*)theApp.m_TextComposeTemplate->OpenDocumentFile(NULL, NULL, /*win_csid RICHIE*/ winShowFlag);
00205   if ( !pDocument )
00206   {
00207     return(MAPI_E_FAILURE);
00208   }
00209   
00210   CWinCX * pContext = (CWinCX*) pDocument->GetContext();
00211   if ( !pContext ) 
00212   {
00213     return(MAPI_E_FAILURE);
00214   }
00215 
00216   MSG_CompositionPaneCallbacks Callbacks;
00217   Callbacks.CreateRecipientsDialog = CreateRecipientsDialog;
00218   Callbacks.CreateAskHTMLDialog = CreateAskHTMLDialog;
00219 
00220   int16 doccsid;
00221   MWContext *context = pContext->GetContext();
00222   CComposeFrame *pCompose = (CComposeFrame *) pContext->GetFrame()->GetFrameWnd();
00223 
00224   pCompose->SetComposeStuff(context, fields); // squirl away stuff for post-create
00225 
00226   // This needs to be set TRUE if using the old non-HTML text frame
00227   // to prevent dropping dragged URLs
00228   pContext->m_bDragging = !pCompose->UseHtml();
00229   if (!pCompose->UseHtml()) 
00230   {
00231     pCompose->SetMsgPane(
00232       MSG_CreateCompositionPane(pContext->GetContext(), 
00233                                 context, 
00234                                 g_MsgPrefs.m_pMsgPrefs, 
00235                                 fields,
00236                                 WFE_MSGGetMaster())
00237                         );
00238   }
00239 
00240   ASSERT(pCompose->GetMsgPane());
00241   MSG_SetFEData(pCompose->GetMsgPane(),(void *)pCompose);  
00242   pCompose->UpdateAttachmentInfo();
00243 
00244   // Pass doccsid info to new context for MailToWin conversion
00245   doccsid = INTL_GetCSIDocCSID(LO_GetDocumentCharacterSetInfo(context));
00246   INTL_SetCSIDocCSID(LO_GetDocumentCharacterSetInfo(context), 
00247     (doccsid ? doccsid : INTL_DefaultDocCharSetID(context)));
00248 
00249   pCompose->DisplayHeaders(NULL);
00250 
00251   CComposeBar * pBar = pCompose->GetComposeBar();
00252   ASSERT(pBar);
00253   LPADDRESSCONTROL pIAddressList = pBar->GetAddressWidgetInterface();
00254 
00255   if (!pIAddressList->IsCreated()) 
00256   {
00257     pBar->CreateAddressingBlock();
00258   }
00259 
00260   // rhp - Deal with addressing the brute force way! This is a 
00261   // "fix" for bad behavior when creating these windows and not
00262   // showing them on the desktop.
00263   if (!winShowFlag)      // Hack to fix the window not being mapped
00264   {
00265     pCompose->AppendAddress(MSG_TO_HEADER_MASK, "");
00266     pCompose->AppendAddress(MSG_CC_HEADER_MASK, "");
00267     pCompose->AppendAddress(MSG_BCC_HEADER_MASK, "");
00268   }
00269 
00270   // Always do plain text composition!
00271   pCompose->CompleteComposeInitialization();
00272 
00273   // Do this so we don't get popups on "empty" messages
00274   if ( (!pInitialText) || (!(*pInitialText)) )
00275     pInitialText = " ";
00276 
00277   const char * pBody = pInitialText ? pInitialText : MSG_GetCompBody(pCompose->GetMsgPane());
00278   if (pBody)
00279   {
00280     FE_InsertMessageCompositionText(context,pBody,TRUE);
00281   }
00282 
00283   // 
00284   // Now set the message as being edited!    
00285   //
00286   pCompose->SetModified(TRUE);
00287 
00288   //
00289   // Finally deal with the attachments...
00290   //
00291   if (sendMailPtr->MSG_nFileCount > 0)
00292   {
00293     // Send this puppy when done with the attachments...
00294     if (!winShowFlag)
00295     {
00296       pCompose->SetMAPISendMode(MAPI_SEND);
00297     }
00298 
00299     MSG_AttachmentData *pAttach = (MSG_AttachmentData *)
00300                   XP_CALLOC((sendMailPtr->MSG_nFileCount + 1),
00301                   sizeof(MSG_AttachmentData));
00302     if (!pAttach)
00303     {
00304       return(MAPI_E_INSUFFICIENT_MEMORY);
00305     }
00306 
00307     memset(pAttach, 0, (sendMailPtr->MSG_nFileCount + 1) * 
00308                                 sizeof(MSG_AttachmentData));
00309     for (i=0; i<sendMailPtr->MSG_nFileCount; i++)
00310     {
00311       CString cs;
00312       // Create URL from filename...
00313       WFE_ConvertFile2Url(cs, 
00314           (const char *)NSStrSeqGet(mailInfoSeq, stringCount++));
00315       pAttach[i].url = XP_STRDUP(cs);
00316 
00317       // Now also include the "display" name...
00318       StrAllocCopy(pAttach[i].real_name, NSStrSeqGet(mailInfoSeq, stringCount++));
00319     }
00320 
00321     // Set the list!
00322     MSG_SetAttachmentList(pCompose->GetMsgPane(), pAttach);
00323 
00324     // Now free everything...
00325     for (i=0; i<sendMailPtr->MSG_nFileCount; i++)
00326     {
00327       if (pAttach[i].url)
00328         XP_FREE(pAttach[i].url);
00329 
00330       if (pAttach[i].real_name)
00331         XP_FREE(pAttach[i].real_name);
00332     }
00333 
00334     XP_FREE(pAttach);
00335   }
00336 
00337   //
00338   // Now, if we were supposed to do the blind send...do it, otherwise,
00339   // just popup the window...
00340   //
00341   if (winShowFlag)      
00342   {
00343     // Post message to compose window to set the initial focus.
00344     pCompose->PostMessage(WM_COMP_SET_INITIAL_FOCUS);
00345   }
00346   else if (sendMailPtr->MSG_nFileCount <= 0)  // Send NOW if no attachments!
00347   {
00348     pCompose->PostMessage(WM_COMMAND, IDM_SEND);
00349   }
00350 
00351   return(SUCCESS_SUCCESS);
00352 }
00353 
00354 //
00355 // This function will create a composition window and just attach
00356 // the attachments of interest and pop up the window...
00357 //
00358 // Return: appropriate MAPI return code...
00359 //
00360 //
00361 extern "C" LONG
00362 DoPartialMAPIMailOperation(MAPISendDocumentsType *sendDocPtr)
00363 {   
00364 CGenericDoc             *pDocument;
00365 
00366   // Get a context to use for this call...
00367   MWContext *pOldContext = GetUsableContext();
00368   if (!pOldContext)
00369   {
00370     return(MAPI_E_FAILURE);
00371   }
00372 
00373   // Don't allow a compose window to be created if the user hasn't 
00374   // specified an email address
00375   const char *real_addr = FE_UsersMailAddress();
00376   if (MISC_ValidateReturnAddress(pOldContext, real_addr) < 0)
00377   {
00378     return(MAPI_E_FAILURE);
00379   }
00380 
00381   //
00382   // Now, build the fields object w/o much info...
00383   //
00384   BOOL    bEncrypt = FALSE;
00385   BOOL    bSign    = FALSE;
00386 
00387   PREF_GetBoolPref("mail.crypto_sign_outgoing_mail", &bSign);
00388   PREF_GetBoolPref("mail.encrypt_outgoing_mail", &bEncrypt);
00389 
00390   MSG_CompositionFields *fields =
00391       MSG_CreateCompositionFields(real_addr, real_addr, NULL, 
00392                   "", "",
00393                                                                "", "", "",
00394                                                                "", "", "",
00395                                                                "", "", "",
00396                                                                "", 
00397                   bEncrypt,
00398                   bSign);
00399   if (!fields)
00400   {
00401     return(MAPI_E_FAILURE);
00402   }
00403 
00404   // RICHIE - INTL_CharSetInfo csi = LO_GetDocumentCharacterSetInfo(pOldContext);
00405   // int16 win_csid = INTL_GetCSIWinCSID(csi);
00406 
00407   pDocument = (CGenericDoc*)theApp.m_TextComposeTemplate->OpenDocumentFile(NULL, NULL, /*RICHIE win_csid,*/ TRUE);
00408   if ( !pDocument )
00409   {
00410     // cleanup fields object
00411     MSG_DestroyCompositionFields(fields);
00412     return(MAPI_E_FAILURE);
00413   }
00414 
00415   CWinCX * pContext = (CWinCX*) pDocument->GetContext();
00416   if ( !pContext ) 
00417   {
00418     return(MAPI_E_FAILURE);
00419   }
00420 
00421   MSG_CompositionPaneCallbacks Callbacks;
00422   Callbacks.CreateRecipientsDialog = CreateRecipientsDialog;
00423   Callbacks.CreateAskHTMLDialog = CreateAskHTMLDialog;
00424 
00425   MWContext *context = pContext->GetContext();
00426   CComposeFrame *pCompose = (CComposeFrame *) pContext->GetFrame()->GetFrameWnd();
00427   pCompose->SetComposeStuff(context,fields); // squirl away stuff for post-create
00428 
00429   // This needs to be set TRUE if using the old non-HTML text frame
00430   // to prevent dropping dragged URLs
00431   pContext->m_bDragging = !pCompose->UseHtml();
00432   if (!pCompose->UseHtml()) 
00433   {
00434     pCompose->SetMsgPane(MSG_CreateCompositionPane(
00435       pContext->GetContext(), 
00436       context,
00437       g_MsgPrefs.m_pMsgPrefs, fields,
00438       WFE_MSGGetMaster()));
00439   }
00440 
00441   ASSERT(pCompose->GetMsgPane());
00442   MSG_SetFEData(pCompose->GetMsgPane(),(void *)pCompose);
00443 
00444   pCompose->UpdateAttachmentInfo();
00445 
00446   // Pass doccsid info to new context for MailToWin conversion
00447   /***
00448   doccsid = INTL_GetCSIDocCSID(LO_GetDocumentCharacterSetInfo(pOldContext));
00449 
00450   INTL_SetCSIDocCSID(LO_GetDocumentCharacterSetInfo(context), 
00451     (doccsid ? doccsid : INTL_DefaultDocCharSetID(pOldContext)));
00452   ****/
00453 
00454   pCompose->DisplayHeaders(NULL);
00455 
00456   CComposeBar * pBar = pCompose->GetComposeBar();
00457   ASSERT(pBar);
00458   LPADDRESSCONTROL pIAddressList = pBar->GetAddressWidgetInterface();
00459 
00460   if (!pIAddressList->IsCreated()) 
00461   {
00462     pBar->CreateAddressingBlock();
00463   }
00464 
00465   // Always do plain text composition!
00466   pCompose->CompleteComposeInitialization();
00467 
00468   //
00469   // Finally deal with the attachments...
00470   //
00471   NSstringSeq     mailInfoSeq = (NSstringSeq) &(sendDocPtr->dataBuf[0]);
00472   DWORD           stringCount = 0;
00473   DWORD           i;
00474 
00475   TRACE("MAPI: ProcessMAPISendDocuments() # of Attachments = [%d]\n", sendDocPtr->nFileCount);
00476 
00477   if (sendDocPtr->nFileCount > 0)
00478   {
00479       MSG_AttachmentData *pAttach = (MSG_AttachmentData *)
00480                     XP_CALLOC((sendDocPtr->nFileCount + 1),
00481                     sizeof(MSG_AttachmentData));
00482       if (!pAttach)
00483       {
00484         return(MAPI_E_INSUFFICIENT_MEMORY);
00485       }
00486 
00487       memset(pAttach, 0, (sendDocPtr->nFileCount + 1) * 
00488                                   sizeof(MSG_AttachmentData));
00489       for (i=0; i<sendDocPtr->nFileCount; i++)
00490       {
00491         CString cs;
00492         // Create URL from filename...
00493         WFE_ConvertFile2Url(cs, 
00494             (const char *)NSStrSeqGet(mailInfoSeq, stringCount++));
00495         pAttach[i].url = XP_STRDUP(cs);
00496 
00497         // Now also include the "display" name...
00498         StrAllocCopy(pAttach[i].real_name, NSStrSeqGet(mailInfoSeq, stringCount++));
00499       }
00500 
00501       // Set the list!
00502       MSG_SetAttachmentList(pCompose->GetMsgPane(), pAttach);
00503 
00504       // Now free everything...
00505       for (i=0; i<sendDocPtr->nFileCount; i++)
00506       {
00507         if (pAttach[i].url)
00508           XP_FREE(pAttach[i].url);
00509 
00510         if (pAttach[i].real_name)
00511           XP_FREE(pAttach[i].real_name);
00512       }
00513 
00514       XP_FREE(pAttach);
00515   }
00516     
00517   // 
00518   // Now some checking for ... well I'm not sure...
00519   //
00520   if (MSG_GetAttachmentList(pCompose->GetMsgPane()))
00521     pCompose->SetModified(TRUE);
00522   else
00523     pCompose->SetModified(FALSE);
00524 
00525   // Post message to compose window to set the initial focus.
00526   pCompose->PostMessage(WM_COMP_SET_INITIAL_FOCUS);
00527 
00528   //
00529   // Now, just popup the window...
00530   //
00531   pCompose->ShowWindow(TRUE);
00532 
00533   // return pCompose->GetMsgPane(); rhp - used to return the MsgPane
00534   return(SUCCESS_SUCCESS);
00535 }
00536 
00537 static void _GetMailCallback(HWND hwnd, MSG_Pane *pane, void *closure)
00538 {
00539    if (pane != NULL)
00540    {
00541      ShowWindow(hwnd, SW_HIDE);
00542      MSG_Command( pane, MSG_GetNewMail, NULL, 0 );
00543    }
00544 }
00545 
00546 static void _GetMailDoneCallback(HWND hwnd, MSG_Pane *pane, void *closure)
00547 {
00548        for(CGenericFrame * f = theApp.m_pFrameList; f; f = f->m_pNext)
00549               f->PostMessage(WM_COMMAND, (WPARAM) ID_DONEGETTINGMAIL, (LPARAM) 0);
00550 }
00551 
00552 //
00553 // This will fire off a "get mail in background operation" in an
00554 // async. fashion.
00555 //
00556 extern "C" void
00557 MAPIGetNewMessagesInBackground(void)
00558 {
00559 CGenericFrame     *pFrame = (CGenericFrame * )FEU_GetLastActiveFrame();
00560 
00561   // rhp - we should not hit the net if we are offline!
00562   if (NET_IsOffline())
00563     return;
00564 
00565   if (!pFrame)
00566     return;
00567 
00568   MWContext *pOldContext = GetUsableContext();
00569   if (!pOldContext)
00570     return;
00571 
00572   TRACE("MAPI: DOWNLOAD MAIL IN BACKGROUND\n");
00573   new CProgressDialog(
00574                 pFrame->GetFrameWnd(), 
00575                 NULL, 
00576                 _GetMailCallback, NULL, NULL, 
00577                 _GetMailDoneCallback);
00578 }
00579 
00580 //
00581 // This function will save a message into the Communicator "Drafts"
00582 // folder with no UI showing.
00583 //
00584 // Return: appropriate MAPI return code...
00585 //
00586 //
00587 extern "C" LONG 
00588 DoMAPISaveMailOperation(MAPISendMailType      *sendMailPtr,
00589                                                                                const char            *pInitialText)
00590 {
00591 CGenericDoc             *pDocument;
00592 LPSTR                   subject;
00593 NSstringSeq             mailInfoSeq;
00594 DWORD                   stringCount = 6;
00595 DWORD                   i;
00596 BOOL                    winShowFlag = FALSE;
00597 
00598   // Get a context to use for this call...
00599   MWContext *pOldContext = GetUsableContext();
00600   if (!pOldContext)
00601   {
00602     return(MAPI_E_FAILURE);
00603   }
00604 
00605   // Don't allow a compose window to be created if the user hasn't 
00606   // specified an email address
00607   const char *real_addr = FE_UsersMailAddress();
00608   if (MISC_ValidateReturnAddress(pOldContext, real_addr) < 0)
00609   {
00610     return(MAPI_E_FAILURE);
00611   }
00612 
00613   //
00614   // Now, we must build the fields object...
00615   //
00616   mailInfoSeq = (NSstringSeq) &(sendMailPtr->dataBuf[0]);
00617   subject = NSStrSeqGet(mailInfoSeq, 0);
00618 
00619   TRACE("MAPI: ProcessMAPISendMail() Subject   = [%s]\n", subject);
00620   TRACE("MAPI: ProcessMAPISendMail() Text Size = [%d]\n", strlen((const char *)pInitialText));
00621   TRACE("MAPI: ProcessMAPISendMail() # of Recipients  = [%d]\n", sendMailPtr->MSG_nRecipCount);
00622 
00623 
00624   char  toString[1024] = "";
00625   char  ccString[1024] = "";
00626   char  bccString[1024] = "";
00627 
00628   for (i=0; i<sendMailPtr->MSG_nRecipCount; i++)
00629   {
00630     LPSTR   ptr;
00631     UCHAR   tempString[256];
00632 
00633     ULONG addrType = atoi(NSStrSeqGet(mailInfoSeq, stringCount++));
00634 
00635     // figure which type of address this is?
00636     if (addrType == MAPI_CC)
00637       ptr = ccString;
00638     else if (addrType == MAPI_BCC)
00639       ptr = bccString;
00640     else
00641       ptr = toString;
00642 
00643     LPSTR namePtr = (LPSTR) NSStrSeqGet(mailInfoSeq, stringCount++);
00644     LPSTR emailPtr = (LPSTR) NSStrSeqGet(mailInfoSeq, stringCount++);
00645 
00646     if ( (!emailPtr) && (!namePtr))
00647     {
00648       return(MAPI_E_INVALID_RECIPS);
00649     }
00650 
00651     if (!emailPtr)
00652       emailPtr = namePtr;
00653 
00654     char *tptr = strchr(emailPtr, ':');
00655     if (tptr != NULL)
00656     {
00657       if ( (*tptr != '\0') && (*(tptr+1) != '\0') )
00658       {
00659         emailPtr = (tptr + 1);
00660       }
00661     }
00668     // Now build the temp string to tack on in the format
00669     // "Rich Pizzarro" <rhp@netscape.com>
00670     wsprintf((LPSTR) tempString, "\"%s\" <%s>", namePtr, emailPtr);
00671 
00672     // add a comma if not the first one
00673     if (ptr[0] != '\0')
00674       lstrcat(ptr, ",");
00675 
00676     // tack on string!
00677     lstrcat(ptr, (LPSTR) tempString);
00678   }
00679 
00680   BOOL    bEncrypt = FALSE;
00681   BOOL    bSign    = FALSE;
00682 
00683   PREF_GetBoolPref("mail.crypto_sign_outgoing_mail", &bSign);
00684   PREF_GetBoolPref("mail.encrypt_outgoing_mail", &bEncrypt);
00685   MSG_CompositionFields *fields =
00686       MSG_CreateCompositionFields(real_addr, real_addr, 
00687                   toString, 
00688                   ccString, 
00689                   bccString,
00690                                                                "", "", "",
00691                                                                "", subject, "",
00692                                                                "", "", "",
00693                                                                "", 
00694                   bEncrypt,
00695                   bSign);
00696   if (!fields)
00697   {
00698     return(MAPI_E_FAILURE);
00699   }
00700 
00701   // RICHIE
00702   // INTL_CharSetInfo csi = LO_GetDocumentCharacterSetInfo(pOldContext);
00703   // int16 win_csid = INTL_GetCSIWinCSID(csi);
00704   
00705   pDocument = (CGenericDoc*)theApp.m_TextComposeTemplate->OpenDocumentFile(NULL, NULL, /*win_csid RICHIE*/ winShowFlag);
00706   if ( !pDocument )
00707   {
00708     return(MAPI_E_FAILURE);
00709   }
00710   
00711   CWinCX * pContext = (CWinCX*) pDocument->GetContext();
00712   if ( !pContext ) 
00713   {
00714     return(MAPI_E_FAILURE);
00715   }
00716 
00717   MSG_CompositionPaneCallbacks Callbacks;
00718   Callbacks.CreateRecipientsDialog = CreateRecipientsDialog;
00719   Callbacks.CreateAskHTMLDialog = CreateAskHTMLDialog;
00720 
00721   int16 doccsid;
00722   MWContext *context = pContext->GetContext();
00723   CComposeFrame *pCompose = (CComposeFrame *) pContext->GetFrame()->GetFrameWnd();
00724 
00725   pCompose->SetComposeStuff(context, fields); // squirl away stuff for post-create
00726 
00727   // This needs to be set TRUE if using the old non-HTML text frame
00728   // to prevent dropping dragged URLs
00729   pContext->m_bDragging = !pCompose->UseHtml();
00730   if (!pCompose->UseHtml()) 
00731   {
00732     pCompose->SetMsgPane(
00733       MSG_CreateCompositionPane(pContext->GetContext(), 
00734                                 context, 
00735                                 g_MsgPrefs.m_pMsgPrefs, 
00736                                 fields,
00737                                 WFE_MSGGetMaster())
00738                         );
00739   }
00740 
00741   ASSERT(pCompose->GetMsgPane());
00742   MSG_SetFEData(pCompose->GetMsgPane(),(void *)pCompose);  
00743   pCompose->UpdateAttachmentInfo();
00744 
00745   // Pass doccsid info to new context for MailToWin conversion
00746   doccsid = INTL_GetCSIDocCSID(LO_GetDocumentCharacterSetInfo(context));
00747   INTL_SetCSIDocCSID(LO_GetDocumentCharacterSetInfo(context), 
00748     (doccsid ? doccsid : INTL_DefaultDocCharSetID(context)));
00749 
00750   pCompose->DisplayHeaders(NULL);
00751 
00752   CComposeBar * pBar = pCompose->GetComposeBar();
00753   ASSERT(pBar);
00754   LPADDRESSCONTROL pIAddressList = pBar->GetAddressWidgetInterface();
00755 
00756   if (!pIAddressList->IsCreated()) 
00757   {
00758     pBar->CreateAddressingBlock();
00759   }
00760 
00761   // rhp - Deal with addressing the brute force way! This is a 
00762   // "fix" for bad behavior when creating these windows and not
00763   // showing them on the desktop.
00764   if (!winShowFlag)      // Hack to fix the window not being mapped
00765   {
00766     pCompose->AppendAddress(MSG_TO_HEADER_MASK, "");
00767     pCompose->AppendAddress(MSG_CC_HEADER_MASK, "");
00768     pCompose->AppendAddress(MSG_BCC_HEADER_MASK, "");
00769   }
00770 
00771   // Always do plain text composition!
00772   pCompose->CompleteComposeInitialization();
00773 
00774   // Do this so we don't get popups on "empty" messages
00775   if ( (!pInitialText) || (!(*pInitialText)) )
00776     pInitialText = " ";
00777 
00778   const char * pBody = pInitialText ? pInitialText : MSG_GetCompBody(pCompose->GetMsgPane());
00779   if (pBody)
00780   {
00781     FE_InsertMessageCompositionText(context,pBody,TRUE);
00782   }
00783 
00784   // 
00785   // Now set the message as being edited!    
00786   //
00787   pCompose->SetModified(TRUE);
00788 
00789   //
00790   // Finally deal with the attachments...
00791   //
00792   if (sendMailPtr->MSG_nFileCount > 0)
00793   {
00794     // Send this puppy when done with the attachments...
00795     if (!winShowFlag)
00796     {
00797       pCompose->SetMAPISendMode(MAPI_SAVE);
00798     }
00799 
00800     MSG_AttachmentData *pAttach = (MSG_AttachmentData *)
00801                   XP_CALLOC((sendMailPtr->MSG_nFileCount + 1),
00802                   sizeof(MSG_AttachmentData));
00803     if (!pAttach)
00804     {
00805       return(MAPI_E_INSUFFICIENT_MEMORY);
00806     }
00807 
00808     memset(pAttach, 0, (sendMailPtr->MSG_nFileCount + 1) * 
00809                                 sizeof(MSG_AttachmentData));
00810     for (i=0; i<sendMailPtr->MSG_nFileCount; i++)
00811     {
00812       CString cs;
00813       // Create URL from filename...
00814       WFE_ConvertFile2Url(cs, 
00815           (const char *)NSStrSeqGet(mailInfoSeq, stringCount++));
00816       pAttach[i].url = XP_STRDUP(cs);
00817 
00818       // Now also include the "display" name...
00819       StrAllocCopy(pAttach[i].real_name, NSStrSeqGet(mailInfoSeq, stringCount++));
00820     }
00821 
00822     // Set the list!
00823     MSG_SetAttachmentList(pCompose->GetMsgPane(), pAttach);
00824 
00825     // Now free everything...
00826     for (i=0; i<sendMailPtr->MSG_nFileCount; i++)
00827     {
00828       if (pAttach[i].url)
00829         XP_FREE(pAttach[i].url);
00830 
00831       if (pAttach[i].real_name)
00832         XP_FREE(pAttach[i].real_name);
00833     }
00834 
00835     XP_FREE(pAttach);
00836   }
00837 
00838   //
00839   // Now, if we were supposed to do the blind send...do it, otherwise,
00840   // just popup the window...
00841   //
00842   if (winShowFlag)      
00843   {
00844     // Post message to compose window to set the initial focus.
00845     pCompose->PostMessage(WM_COMP_SET_INITIAL_FOCUS);
00846   }
00847   else if (sendMailPtr->MSG_nFileCount <= 0)  // Send NOW if no attachments!
00848   {
00849     pCompose->PostMessage(WM_COMMAND, IDM_SAVEASDRAFT);
00850   }
00851 
00852   return(SUCCESS_SUCCESS);
00853 }