home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / winfe / compfrm.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  56.1 KB  |  1,843 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. /* COMPFRM.CPP - Compose Window Frame.  This module contains code for the
  20.  * compose window frame class.  Handles all menu and tool commands.
  21.  *
  22.  */
  23.  
  24. #include "stdafx.h"
  25. #include "edt.h"
  26. #include "compbar.h"
  27. #include "compfrm.h"
  28. #include "prefapi.h"
  29. #include "intl_csi.h"
  30.  
  31. extern "C" {
  32. #include "xpgetstr.h"
  33. extern int MK_MSG_SAVE_AS;
  34. extern int MK_MSG_CANT_OPEN;
  35. extern int MK_MSG_MISSING_SUBJECT;
  36. };
  37.  
  38. #ifdef XP_WIN32
  39. #include "postal.h"
  40. #endif
  41.  
  42. #define COMPOSE_WINDOW_WIDTH    73 // default to 73 characters wide
  43.  
  44. /////////////////////////////////////////////////////////////////////////////
  45. // CComposeFrame
  46.  
  47. // This is for mail that is sent immediately
  48. static UINT ComposeCodes[] = {
  49.    IDM_SENDNOW,
  50.    IDM_QUOTEORIGINAL,
  51.    IDM_ADDRESSPICKER,
  52.    ID_CHECK_SPELLING,
  53.    IDM_SAVEASDRAFT,
  54.    ID_SECURITY,
  55.    ID_NAVIGATE_INTERRUPT
  56.     };
  57.  
  58. static BOOL bSendDeferred = FALSE;
  59.  
  60. BEGIN_MESSAGE_MAP(CComposeFrame, CGenericFrame)
  61.    ON_WM_CREATE()
  62.    ON_WM_CLOSE()
  63.    ON_WM_SETFOCUS()
  64.    ON_MESSAGE(WM_SETMESSAGESTRING, OnSetMessageString)
  65.    ON_MESSAGE(NSBUTTONMENUOPEN, OnButtonMenuOpen)
  66.    ON_MESSAGE(WM_TOOLCONTROLLER,OnToolController)
  67.    ON_COMMAND(ID_CHECK_SPELLING, OnCheckSpelling)
  68.    ON_COMMAND(IDM_PASTEASQUOTE, OnPasteQuote)
  69.    ON_UPDATE_COMMAND_UI(IDM_PASTEASQUOTE, OnUpdatePasteQuote)
  70.    ON_COMMAND(ID_EDIT_SELECTALLMESSAGES, OnSelectAll)
  71.    ON_UPDATE_COMMAND_UI(ID_EDIT_SELECTALLMESSAGES,OnUpdateSelectAll)
  72.    ON_COMMAND(IDM_SEND, OnSend)
  73.    ON_UPDATE_COMMAND_UI(IDM_SEND, OnUpdateSend)
  74.    ON_COMMAND(IDM_SENDNOW, OnSendNow)
  75.    ON_UPDATE_COMMAND_UI(IDM_SENDNOW, OnUpdateSendNow)
  76.    ON_COMMAND(IDM_SENDLATER, OnSendLater)
  77.    ON_UPDATE_COMMAND_UI(IDM_SENDLATER,OnUpdateSendLater)
  78.    ON_COMMAND(IDM_QUOTEORIGINAL, OnQuoteOriginal)
  79.    ON_UPDATE_COMMAND_UI(IDM_QUOTEORIGINAL,OnUpdateButtonGeneral)
  80.    ON_COMMAND(IDM_SAVEAS, OnSaveAs)
  81.    ON_UPDATE_COMMAND_UI(IDM_SAVEAS, OnUpdateButtonGeneral)
  82.    ON_COMMAND(IDM_SAVEASDRAFT, OnSaveDraft)
  83.    ON_UPDATE_COMMAND_UI(IDM_SAVEASDRAFT, OnUpdateSaveDraft)
  84.    ON_COMMAND(IDM_SAVEASTEMPLATE, OnSaveTemplate)
  85.    ON_UPDATE_COMMAND_UI(IDM_SAVEASTEMPLATE, OnUpdateSaveTemplate)
  86.    ON_COMMAND(IDM_CONVERT,OnConvert)
  87.    ON_UPDATE_COMMAND_UI(IDM_CONVERT, OnUpdateConvert)
  88.    ON_COMMAND(IDM_ATTACHFILE,OnAttachFile)
  89.    ON_COMMAND(ID_SECURITY,OnSecurity)
  90.    ON_UPDATE_COMMAND_UI(ID_SECURITY,OnUpdateSecurity)
  91.    
  92.    ON_COMMAND(ID_DONEGOINGOFFLINE, OnDoneGoingOffline)
  93.  
  94.    ON_WM_DESTROY()
  95.    ON_BN_CLICKED(IDM_ATTACHFILE, OnAttachFile)
  96.    ON_BN_CLICKED(IDM_ATTACHWEBPAGE, OnAttachUrl)
  97.    ON_COMMAND(IDM_ADDRESSPICKER,OnSelectAddresses)
  98.    ON_COMMAND(ID_MAIL_WRAPLONGLINES,OnWrapLongLines)
  99.    ON_UPDATE_COMMAND_UI(ID_MAIL_WRAPLONGLINES,OnUpdateWrapLongLines)    
  100.    ON_COMMAND(IDM_ATTACHMYCARD,OnAttachMyCard)
  101.    ON_UPDATE_COMMAND_UI(IDM_ATTACHMYCARD,OnUpdateAttachMyCard)
  102.    ON_COMMAND(ID_FILE_NEWMESSAGE, OnNew)
  103.    ON_COMMAND(IDM_ADDRESSES,OnViewAddresses)
  104.    ON_COMMAND(IDM_ATTACHMENTS,OnViewAttachments)
  105.    ON_COMMAND(IDM_OPTIONS,OnViewOptions)
  106.    ON_COMMAND(IDC_ADDRESSTAB,OnAddressTab)
  107.    ON_COMMAND(IDC_ATTACHTAB,OnAttachTab)
  108.    ON_COMMAND(IDC_OPTIONSTAB,OnOptionsTab)
  109.    ON_COMMAND(IDC_COLLAPSE,OnCollapse)
  110.    ON_UPDATE_COMMAND_UI(ID_CHECK_SPELLING, OnUpdateButtonGeneral)
  111.    ON_UPDATE_COMMAND_UI(IDM_ADDRESSES,OnUpdateViewAddresses)
  112.    ON_UPDATE_COMMAND_UI(IDM_ATTACHMENTS,OnUpdateViewAttachments)
  113.    ON_UPDATE_COMMAND_UI(IDM_OPTIONS,OnUpdateViewOptions)
  114.    ON_REGISTERED_MESSAGE(WM_FINDREPLACE, OnFindReplace)
  115.    // general button enabler, these should be enabled as long as the
  116.    // compose window is visible
  117.    ON_UPDATE_COMMAND_UI(ID_VIEW_ADDRESSES, OnUpdateButtonGeneral)
  118.    ON_UPDATE_COMMAND_UI(IDC_ADDRESS,OnUpdateButtonGeneral)
  119.    ON_UPDATE_COMMAND_UI(IDC_DIRECTORY,OnUpdateButtonGeneral)
  120.    ON_UPDATE_COMMAND_UI(IDM_ATTACHFILE,OnUpdateButtonGeneral) 
  121.    ON_UPDATE_COMMAND_UI(IDM_ATTACHWEBPAGE,OnUpdateButtonGeneral)
  122.    ON_UPDATE_COMMAND_UI(IDM_ADDRESSPICKER,OnUpdateButtonGeneral) 
  123.  
  124.    ON_COMMAND(IDM_MESSAGEBODYONLY,OnToggleAddressArea)
  125.    ON_UPDATE_COMMAND_UI(IDM_MESSAGEBODYONLY,OnUpdateToggleAddressArea)
  126.    ON_COMMAND(IDM_OPT_MESSAGEBAR_TOGGLE, OnToggleMessageToolbar)
  127.    ON_UPDATE_COMMAND_UI(IDM_OPT_MESSAGEBAR_TOGGLE, OnUpdateToggleMessageToolbar)
  128.  
  129.     // Security Stuff 
  130.        ON_UPDATE_COMMAND_UI(IDS_SECURITY_STATUS, OnUpdateSecureStatus)
  131.     ON_UPDATE_COMMAND_UI(IDS_SIGNED_STATUS, OnUpdateSecureStatus)
  132.  
  133.  
  134. END_MESSAGE_MAP()
  135.  
  136. #ifndef _AFXDLL
  137. #undef new
  138. #endif
  139. IMPLEMENT_DYNCREATE(CComposeFrame,CGenericFrame)
  140. #ifndef _AFXDLL
  141. #define new DEBUG_NEW
  142. #endif
  143.  
  144. #ifdef XP_WIN32
  145. char *ToolBarProfileName = "MailComposeToolBar";
  146. #endif
  147.  
  148. // Constructor for CCompFrame.  Creates the toolbar controller object.
  149. // This object is used by the Gold editor to display/control the
  150. // HTML toolbar commands.  Initialize local variables, set the deferred
  151. // flag to the last known state
  152.  
  153. CComposeFrame::CComposeFrame()
  154. {
  155.     PREF_GetBoolPref("network.online", &bSendDeferred);
  156.    bSendDeferred = !bSendDeferred;
  157.     m_bUseHtml = FALSE;
  158.     m_pToolBarController = NULL;
  159.    m_pComposeBar = NULL;                               // dialog bar
  160.     m_pComposePane = NULL;                              // message pane (for backend)
  161.    m_pFocus = NULL;                                    // current field with focus
  162.    m_bInitialized = FALSE;
  163.     m_pInitialText = NULL;
  164.    m_bWrapLongLines = TRUE;
  165.    m_cxChar = 0;
  166.    m_quoteSel = -1;                // no quoting selection yet
  167.  
  168.    m_bMAPISendMode = MAPI_IGNORE;   // rhp - For MAPI UI-less send/save operations
  169. }
  170.  
  171. // The menu gets cleaned up on window destruction but we need
  172. // to delete our accelerator table ourselves
  173.  
  174. CComposeFrame::~CComposeFrame()
  175. {
  176.     // free the accelerator table
  177.     if(m_hAccelTable != NULL)   {
  178.         ::FreeResource((HGLOBAL)m_hAccelTable);
  179.         m_hAccelTable = NULL;
  180.     }
  181.     if (m_pToolBarController)
  182.         delete m_pToolBarController;
  183.     // free up the dialog bar (address & attachment controls)
  184.     if (m_pComposeBar)
  185.         delete m_pComposeBar;
  186. }
  187.  
  188.  
  189. // GetAddressWidget() returns the current address control widget.
  190.  
  191. LPADDRESSCONTROL CComposeFrame::GetAddressWidgetInterface() 
  192. {
  193.     ASSERT(m_pComposeBar);
  194.     return m_pComposeBar->GetAddressWidgetInterface();
  195. }    
  196.  
  197. // AppendAddress() adds a header/value to the current address block.  It 
  198. // accepts a MSG_HEADER_SET value which is translated to the appropriate 
  199. // corresponding string and appended to the end of the address list with 
  200. // the supplied value.
  201. // Returns TRUE on success, FALSE otherwise.
  202.  
  203. BOOL CComposeFrame::AppendAddress(
  204.     MSG_HEADER_SET header,  // header to add
  205.     const char * value      // header value (or NULL for empty)
  206.     )
  207. {
  208.     // check for a valid widget 
  209.     if (::IsWindow(m_pComposeBar->m_hWnd))
  210.     {
  211.         // get a pointer to the addressing block widget
  212.         LPADDRESSCONTROL pIAddress = GetAddressWidgetInterface();
  213.         if (pIAddress)
  214.         {
  215.             CListBox * pListBox = pIAddress->GetListBox();        
  216.             // check to make sure we got a valid list and the list
  217.             // has a valid window
  218.             if (::IsWindow(pListBox->m_hWnd))
  219.             {
  220.                 const char * szType = MSG_HeaderMaskToString(header);
  221.                 if (!szType)
  222.                     return FALSE;
  223.                 // add the entry to the list
  224.                 pIAddress->AppendEntry(TRUE, szType,value ? value : "", 0, 0);
  225.             }
  226.         }
  227.     }
  228.     return TRUE;
  229. }
  230.  
  231. // destroy message compose pane
  232. void CComposeFrame::OnDestroy()
  233. {
  234.     MSG_DestroyPane(m_pComposePane);
  235.     m_pComposePane = NULL;
  236.     CGenericFrame::OnDestroy();
  237. }
  238.  
  239. int CComposeFrame::CreateHtmlToolbars()
  240. {
  241.    // Create the HTML edit toolbars.  There are currently two separate
  242.    // toolbars.. one for formats and another for character operations.
  243.    m_pToolBarController = new CEditToolBarController(this);
  244.    ASSERT(m_pToolBarController);
  245.    if (!m_pToolBarController->CreateEditBars(GetMainContext()->GetContext(), DISPLAY_CHARACTER_TOOLBAR))
  246.       return -1;      // fail to create
  247.    return 0;
  248. }
  249.  
  250. void CComposeFrame::DestroyHtmlToolbars()
  251. {
  252.    XP_Bool prefBool;
  253.    PREF_GetBoolPref("editor.show_character_toolbar",&prefBool);
  254.    if ( prefBool ) 
  255.    {
  256.       CWnd * pWnd = m_pToolBarController->GetCharacterBar();
  257.       if (pWnd && ::IsWindow(pWnd->m_hWnd))
  258.          pWnd->DestroyWindow();
  259.    }
  260. }
  261.  
  262. void CComposeFrame::ShowHtmlToolbars()
  263. {
  264.    // display the appropriate toolbars for HTML editing based on 
  265.    // configuration.
  266.    XP_Bool prefBool;
  267.    PREF_GetBoolPref("editor.show_character_toolbar",&prefBool);
  268.    if ( prefBool ) 
  269.       m_pToolBarController->GetCharacterBar()->ShowWindow(SW_SHOW);
  270. }
  271.  
  272. void CComposeFrame::SetMsgPane(MSG_Pane * pPane) 
  273.     m_pComposePane = pPane; 
  274. }
  275.  
  276. void CComposeFrame::CreatePlainTextEditor()
  277. {
  278.    CWnd *pView = GetDescendantWindow(AFX_IDW_PANE_FIRST, TRUE);
  279.    ASSERT(pView);
  280.  
  281.    // create the editor parent.  This is a window whose sole purpose is to
  282.    // resize the edit control... this will go away when the Gold editor
  283.    // is fully integrated.
  284.  
  285.    CRect rect(0,0,0,0);   
  286.    if (::IsWindow(pView->m_hWnd) && pView->IsWindowVisible())
  287.       pView->GetClientRect(rect);
  288.    
  289.    m_EditorParent.Create ( 
  290.       NULL, NULL, WS_VISIBLE | WS_CHILD,  rect, pView, 0 );        
  291.  
  292.    SetEditorParent((CWnd*)&m_EditorParent);
  293.  
  294.    // create the editor which is currently a standard windows edit 
  295.    // control.  This will be replaced by the Gold editor.
  296.  
  297.    if (rect.Width())
  298.       rect.left = EDIT_MARGIN_OFFSET;
  299.  
  300.    m_Editor.Create ( 
  301.       WS_VSCROLL | ES_MULTILINE | WS_CHILD | WS_VISIBLE | ES_AUTOVSCROLL | ES_WANTRETURN | ES_NOHIDESEL,
  302.       rect, 
  303.       &m_EditorParent, IDC_COMPOSEEDITOR);
  304.       
  305.    m_Editor.SetComposeFrame(this);
  306.    m_Editor.SetTabStops();
  307.  
  308.    m_cxChar = m_Editor.GetCharWidth();
  309.  
  310.    #ifdef XP_WIN16
  311.    m_Editor.SendMessage(EM_LIMITTEXT,0,0);
  312.    #endif
  313. }
  314.  
  315. // Perform initial setup for the compose window.
  316.  
  317. // status bar format
  318. static const UINT BASED_CODE indicators[] =
  319. {
  320.     IDS_SECURITY_STATUS,
  321.     IDS_SIGNED_STATUS,
  322.     IDS_TRANSFER_STATUS,    
  323.     ID_SEPARATOR,
  324.     IDS_TASKBAR
  325. };
  326.  
  327. int CComposeFrame::OnCreate( LPCREATESTRUCT lpCreateStruct )
  328. {
  329.    int retval = CGenericFrame::OnCreate ( lpCreateStruct );
  330.  
  331.     //I'm hardcoding string since I don't want it translated.
  332.     m_pChrome->CreateCustomizableToolbar("Compose_Message", 3, TRUE);
  333.     CButtonToolbarWindow *pWindow;
  334.     BOOL bOpen, bShowing;
  335.  
  336.     int32 nPos;
  337.  
  338.     m_pChrome->LoadToolbarConfiguration(ID_COMPOSE_MESSAGE_TOOLBAR, CString("Message_Toolbar"),nPos, bOpen, bShowing);
  339.  
  340.     // Set up toolbar
  341.     LPNSTOOLBAR pIToolBar = NULL;
  342.     m_pChrome->QueryInterface(IID_INSToolBar,(LPVOID*)&pIToolBar);
  343.     if ( pIToolBar ) 
  344.    {
  345.         pIToolBar->Create( this );
  346.         pIToolBar->SetButtons( ComposeCodes, sizeof(ComposeCodes) / sizeof(UINT) );
  347.         pIToolBar->SetSizes( CSize( 23+7, 21+6), CSize( 23, 21 ) );
  348.        // this is currently loading one bitmap.. this needs to be fixed to add
  349.        // the deferred bitmaps as well.
  350.         pIToolBar->LoadBitmap(MAKEINTRESOURCE(IDB_COMPOSETOOLBAR));
  351.         pIToolBar->SetToolbarStyle( theApp.m_pToolbarStyle );
  352.         pWindow = new CButtonToolbarWindow(CWnd::FromHandlePermanent(pIToolBar->GetHWnd()), theApp.m_pToolbarStyle, 43, 27, eLARGE_HTAB);
  353.         m_pChrome->GetCustomizableToolbar()->AddNewWindow(ID_COMPOSE_MESSAGE_TOOLBAR, pWindow,nPos, 50, 37, 0, CString(szLoadString(ID_COMPOSE_MESSAGE_TOOLBAR)),theApp.m_pToolbarStyle, bOpen, FALSE);
  354.         m_pChrome->ShowToolbar(ID_COMPOSE_MESSAGE_TOOLBAR, bShowing);
  355.         m_pChrome->GetCustomizableToolbar()->SetBottomBorder(TRUE);
  356.         CWnd *pToolWnd = CWnd::FromHandlePermanent( pIToolBar->GetHWnd() );
  357.         if ( pToolWnd ) {
  358.             CStationaryToolbarButton * pStationaryToolbarButton = new CStationaryToolbarButton;
  359.             pStationaryToolbarButton->Create(pToolWnd, theApp.m_pToolbarStyle, CSize(50, 40), CSize(30, 27), 
  360.                szLoadString(IDS_TOOLATTACH),
  361.                szLoadString(IDS_TOOLATTACHFILES),
  362.                szLoadString(IDS_TOOLATTACHALL),
  363.                     IDB_ATTACHBUTTON, 0, CSize(23, 21), TRUE, IDM_ATTACHFILE, 10, TB_HAS_IMMEDIATE_MENU);
  364.             pIToolBar->AddButton( pStationaryToolbarButton, 3 );
  365.         }
  366.  
  367.       if (bSendDeferred)
  368.       {
  369.            pIToolBar->RemoveButton(0);
  370.               CCommandToolbarButton *pCommandButton = new CCommandToolbarButton;
  371.               CString statusStr, toolTipStr, textStr;
  372.            WFE_ParseButtonString(IDM_SENDLATER, statusStr, toolTipStr, textStr);
  373.            DWORD dwButtonStyle = 0;
  374.            pCommandButton->Create(pToolWnd, theApp.m_pToolbarStyle, CSize(44, 37), CSize(25, 25),
  375.                         (const char*) textStr,(const char*) toolTipStr, (const char*) statusStr,
  376.                         IDB_COMPOSETOOLBAR, 7, CSize(23,21), IDM_SENDLATER, -1, dwButtonStyle);
  377.            pIToolBar->AddButton(pCommandButton, 0);
  378.            CCommandToolbar *pToolBar = (CCommandToolbar *) CWnd::FromHandlePermanent( pIToolBar->GetHWnd() );
  379.            pToolBar->ReplaceButtonBitmapIndex(IDM_SENDNOW,7);
  380.       }
  381.  
  382.         m_pChrome->Release();
  383.     }
  384.  
  385.    // create the address/attachment widget dialog bar
  386.    m_pComposeBar = new CComposeBar;
  387.    ASSERT(m_pComposeBar);
  388.    m_pComposeBar->Create ( this, (UINT) IDD_COMPOSEBAR, 
  389.                            (UINT) WS_CLIPCHILDREN|CBRS_TOP, 
  390.                            (UINT) IDD_COMPOSEBAR );
  391.  
  392.    if (m_bUseHtml)
  393.    {
  394.       if (CreateHtmlToolbars() == -1)
  395.          return -1;
  396.         
  397.       RecalcLayout();        
  398.       // Check if format toolbar needs more room and 
  399.       // increase window width to fit it, but observe 600 pixel maximum width
  400.       int iWidth = min(600, m_pToolBarController->GetCharacterBar()->GetToolbarWidth()
  401.                        + GetSystemMetrics(SM_CXFRAME) + 8); // Kludge - 8 more needed to work right!
  402.  
  403.       if( iWidth > lpCreateStruct->cx ){
  404.          SetWindowPos(NULL, 0, 0, iWidth,
  405.                       lpCreateStruct->cy, SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE);
  406.       }
  407.    }
  408.    else
  409.    {
  410.       CreatePlainTextEditor();
  411.    }
  412.  
  413.    // create a unique title for the composition window    
  414.    CString cs;
  415.    cs = szLoadString(IDS_COMPOSITION);
  416.    GetChrome()->SetWindowTitle(cs);
  417.  
  418.     // Instead of using ANSI_VAR_FONT for i18n
  419.     SetCSID(INTL_DefaultWinCharSetID(0));
  420.  
  421.    // create the status bar
  422.     m_barStatus.Create( this );
  423.     m_barStatus.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT));
  424.  
  425.     LPNSSTATUSBAR pIStatusBar = NULL;
  426.     m_pChrome->QueryInterface( IID_INSStatusBar, (LPVOID *) &pIStatusBar );
  427.     if ( pIStatusBar ) {
  428.         pIStatusBar->Attach( &m_barStatus );
  429.         pIStatusBar->Release();
  430.     }
  431.  
  432.    if (m_bUseHtml)
  433.       ShowHtmlToolbars();
  434.  
  435.     // Attach the submenus shared by Composer, Message Composer, and right-button popups
  436.     HMENU hMenu = ::GetMenu(m_hWnd);
  437.     if( hMenu )
  438.     {
  439.         HMENU hTableMenu = ::GetSubMenu(hMenu, ED_MENU_TABLE);
  440.         if( hTableMenu )
  441.         {
  442.             ::ModifyMenu( hTableMenu, ID_SELECT_TABLE, MF_BYCOMMAND | MF_POPUP | MF_STRING,
  443.                           (UINT)::LoadMenu(AfxGetResourceHandle(), MAKEINTRESOURCE(IDM_COMPOSER_TABLE_SELECTMENU)),
  444.                           szLoadString(IDS_SUBMENU_SELECT_TABLE) );
  445.             ::ModifyMenu( hTableMenu, ID_INSERT_TABLE, MF_BYCOMMAND | MF_POPUP | MF_STRING,
  446.                           (UINT)::LoadMenu(AfxGetResourceHandle(), MAKEINTRESOURCE(IDM_COMPOSER_TABLE_INSERTMENU)),
  447.                           szLoadString(IDS_SUBMENU_INSERT_TABLE) );
  448.             ::ModifyMenu( hTableMenu, ID_DELETE_TABLE, MF_BYCOMMAND | MF_POPUP | MF_STRING,
  449.                           (UINT)::LoadMenu(AfxGetResourceHandle(), MAKEINTRESOURCE(IDM_COMPOSER_TABLE_DELETEMENU)),
  450.                           szLoadString(IDS_SUBMENU_DELETE_TABLE) );
  451.         }
  452.     }
  453.    return retval;
  454. }
  455.  
  456. // OnCreateClient() sets up the context information and create the
  457. // contained CView derived class.
  458.  
  459. BOOL CComposeFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext *pContext)
  460. {
  461.      BOOL bRetval = CGenericFrame::OnCreateClient(lpcs, pContext);
  462.  
  463.     // Get the current view
  464.     CWnd *pView = GetDescendantWindow(AFX_IDW_PANE_FIRST, TRUE);
  465.     ASSERT(pView);
  466.      CWinCX * pWinCX = new CWinCX(
  467.        (CGenericDoc*)pContext->m_pCurrentDoc, this, (CGenericView *)pView );
  468.  
  469.      //      This is the main and active context.
  470.      SetMainContext(pWinCX);
  471.      SetActiveContext(pWinCX);
  472.     RECT rect;
  473.     GetClientRect(&rect);
  474.     pWinCX->Initialize(FALSE, &rect);
  475.     pWinCX->GetContext()->fancyFTP = TRUE;
  476.     pWinCX->GetContext()->fancyNews = TRUE;
  477.     pWinCX->GetContext()->intrupt = FALSE;
  478.     if (m_bUseHtml)
  479.           pWinCX->GetContext()->is_editor = TRUE;
  480.  
  481.     pWinCX->GetContext()->reSize = FALSE;
  482.     return bRetval;
  483. }
  484.  
  485. // PreCreateWindow() sets the initial compose window size based on
  486. // values that were saved in the registry during OnClose().  The width
  487. // is currently hard-coded to open up to 73 (COMPOSE_WINDOW_WIDTH)
  488. // characters wide.
  489.  
  490. BOOL CComposeFrame::PreCreateWindow ( CREATESTRUCT &cs )
  491. {
  492.     cs.style |= WS_CLIPCHILDREN;
  493.  
  494.     BOOL rv = CGenericFrame::PreCreateWindow ( cs );
  495.  
  496.     int16 iLeft,iRight,iTop,iBottom;
  497.     PREF_GetRectPref("mail.compose_window_rect", &iLeft, &iTop, &iRight, &iBottom);
  498.     // Restore X,Y and height, but recalculate width
  499.     if ( iLeft != -1) 
  500.     {
  501.         cs.x = iLeft;
  502.         cs.y = iTop;
  503.         cs.cy = iBottom-iTop;
  504.         if (m_bUseHtml)
  505.         {
  506.             cs.cx = iRight - iLeft;
  507.             return rv;
  508.         }
  509.     } 
  510.  
  511.     CWnd *pCwnd = AfxGetMainWnd();
  512.     ASSERT(pCwnd);
  513.     
  514.     // get the current character width from the font size, first
  515.     // we have to create the font.
  516.     CClientDC dc(pCwnd);
  517.     HFONT font;
  518.     CFont *pOldFont;
  519.     LOGFONT lf;
  520.     XP_MEMSET(&lf,0,sizeof(LOGFONT));
  521.     TEXTMETRIC tm;
  522.  
  523.     lf.lfPitchAndFamily = FF_MODERN | FIXED_PITCH;
  524.     strcpy(lf.lfFaceName, IntlGetUIFixFaceName(0));
  525.     lf.lfHeight = -MulDiv(9,dc.GetDeviceCaps(LOGPIXELSY), 72);
  526.     lf.lfQuality = PROOF_QUALITY;    
  527.     font = theApp.CreateAppFont( lf );
  528.  
  529.     pOldFont = dc.SelectObject(CFont::FromHandle(font));
  530.     dc.GetTextMetrics(&tm);
  531.     dc.SelectObject(pOldFont);
  532.  
  533.     cs.cx = (GetSystemMetrics(SM_CXFRAME)*2) + 
  534.         (tm.tmAveCharWidth*(COMPOSE_WINDOW_WIDTH+(m_bUseHtml?2:0)));
  535.     cs.cx += GetSystemMetrics(SM_CXVSCROLL);
  536.     cs.cx += EDIT_MARGIN_OFFSET;
  537.     
  538.     // use 2/3 of the screen as the standard default height
  539.     cs.cy = (GetSystemMetrics(SM_CYSCREEN)/3)*2;
  540.     theApp.ReleaseAppFont(font);
  541.     return rv;
  542. }
  543.  
  544. void CComposeFrame::DisplayHeaders ( MSG_HEADER_SET headers )
  545. {
  546.    ASSERT(m_pComposeBar);
  547.    m_pComposeBar->DisplayHeaders ( headers );
  548.     m_pComposeBar->UpdateFixedSize ( );
  549.    RecalcLayout ( );
  550. #ifdef XP_WIN16
  551.     m_pComposeBar->Invalidate();
  552. #endif
  553.    m_SavedHeaders = headers;
  554. }
  555.  
  556. LONG CComposeFrame::OnToolController(UINT,LONG)
  557. {
  558.     if (m_bUseHtml)
  559.     return (LONG)m_pToolBarController;
  560.     return 0;
  561. }
  562.  
  563. void CComposeFrame::SetModified(BOOL bValue)
  564. {
  565.     if (m_bUseHtml)
  566.         EDT_SetDirtyFlag(GetMainContext()->GetContext(), bValue);
  567.     else
  568.         m_EditorParent.SetModified(bValue);
  569. }
  570.  
  571. void CComposeFrame::OnSetFocus(CWnd * pOldWnd) 
  572. {
  573.     CGenericFrame::OnSetFocus(pOldWnd);
  574.     if (GetFocusField())
  575.         GetFocusField()->SetFocus();
  576. }
  577.  
  578. BOOL CComposeFrame::CanCloseFrame(void)
  579. {
  580.     BOOL bModified = FALSE;
  581.     if (m_bUseHtml){
  582.         bModified = EDT_DirtyFlag(GetMainContext()->GetContext());
  583.         MWContext *pMWContext;
  584.         if( GetMainContext() == NULL ||
  585.             (pMWContext = GetMainContext()->GetContext()) == NULL )
  586.             return(FALSE);
  587.  
  588.         // Ignore close if in the process of doing something
  589.         if( pMWContext->edit_saving_url ||
  590.             pMWContext->waitingMode ||
  591.             EDT_IsBlocked(pMWContext)  )
  592.             return(FALSE);
  593.     } else
  594.         bModified = m_EditorParent.m_bModified;
  595.  
  596.     if (bModified) 
  597.     {
  598.         CString csText, csTitle;
  599.         csText.LoadString(IDS_MESSAGENOTSENT);
  600.         csTitle.LoadString(IDS_MESSAGECOMPOSITION);
  601.         if(MessageBox( csText, csTitle, MB_YESNO | MB_ICONEXCLAMATION)==IDNO)
  602.              return(FALSE);
  603.     }
  604.     return(TRUE);
  605.     
  606. }
  607.  
  608. void CComposeFrame::OnClose ( void )
  609. {
  610.     // See if the document will allow closing.
  611.     
  612.      if (!CanCloseFrame())
  613.         return;
  614.     
  615.     m_pComposeBar->Cleanup();
  616.     
  617.     if (m_bUseHtml){
  618.         MWContext *pMWContext;
  619.         if( GetMainContext() == NULL ||
  620.             (pMWContext = GetMainContext()->GetContext()) == NULL )
  621.             return;
  622.  
  623.         // Stop any active plugin
  624.         if (!CheckAndCloseEditorPlugin(pMWContext)) 
  625.             return;
  626.         EDT_DestroyEditBuffer(pMWContext);
  627.     }
  628.  
  629.     // Save the window position... as long as it is not iconified or
  630.     // maximized... 
  631.    if ( !IsIconic() && !IsZoomed() )
  632.    {
  633.       CRect rect;
  634.        GetWindowRect ( &rect );
  635.        PREF_SetRectPref("mail.compose_window_rect", 
  636.          (int16)rect.left, (int16)rect.top, (int16)rect.right, (int16)rect.bottom);
  637.     }
  638.         
  639.    CWinCX * pWinCX = (CWinCX*)GetMainContext();
  640.    if ( pWinCX )
  641.    {
  642.        // close the context and stuff
  643.        CGenericView * pView = pWinCX->GetView();
  644.        if ( pView ) 
  645.           pView->FrameClosing ( );
  646.    }
  647.   
  648.     m_pChrome->SaveToolbarConfiguration(ID_COMPOSE_MESSAGE_TOOLBAR, CString("Message_Toolbar"));
  649. #ifdef XP_WIN32
  650.     // Save toolbar state
  651.    CFrameWnd::SaveBarState(ToolBarProfileName);
  652. #endif
  653.    CGenericFrame::OnClose();
  654. }
  655.  
  656. // Used by the template to set the context type.
  657.  
  658. void CComposeFrame::SetType(MWContextType type)
  659. {
  660.     MWContext * xpContext = GetMainContext()->GetContext();
  661.     ASSERT(xpContext);
  662.     xpContext->type = type;
  663. }
  664.  
  665. #ifdef XP_WIN32
  666. int16 CComposeFrame::GetTitleWinCSID()    // jliu - used by genframe.cpp
  667. {
  668.     return INTL_DocToWinCharSetID( m_iCSID );
  669. }
  670. #endif
  671.  
  672. void CComposeFrame::SetCSID(int16 iCSID)
  673. {
  674.    if(iCSID != m_iCSID)
  675.    {    
  676.     m_iCSID = iCSID;
  677.     m_pComposeBar->SetCSID(iCSID);
  678.     if (m_cfTextFont) {
  679.         theApp.ReleaseAppFont(m_cfTextFont);
  680.     }
  681.  
  682.     CClientDC dc(this);
  683.     LOGFONT lf;                 
  684.     XP_MEMSET(&lf,0,sizeof(LOGFONT));
  685.     lf.lfPitchAndFamily = FF_MODERN | FIXED_PITCH;
  686.     strcpy(lf.lfFaceName, IntlGetUIFixFaceName(m_iCSID));
  687.     lf.lfCharSet = IntlGetLfCharset(m_iCSID); 
  688.     lf.lfHeight = -MulDiv(9,dc.GetDeviceCaps(LOGPIXELSY), 72);
  689.     lf.lfQuality = PROOF_QUALITY;    
  690.     m_cfTextFont = theApp.CreateAppFont( lf );
  691.     TEXTMETRIC tm;
  692.     CFont * pOld = dc.SelectObject(CFont::FromHandle(m_cfTextFont));
  693.     dc.GetTextMetrics(&tm);
  694.     dc.SelectObject(pOld);
  695.     m_cxChar = tm.tmAveCharWidth;
  696.  
  697.     if (!m_bUseHtml)
  698.         ::SendMessage(m_Editor.GetSafeHwnd(), WM_SETFONT, (WPARAM)m_cfTextFont, FALSE);
  699.     else
  700.         EDT_SetEncoding(GetMainContext()->GetContext(), m_iCSID);
  701.  
  702. #ifdef XP_WIN32
  703.     // jliu added the following to support CJK caption print
  704.     SendMessage( WM_SETTINGCHANGE );
  705. #endif
  706.  
  707.     RecalcLayout();
  708.    }
  709. }
  710.  
  711. // OnUpdateThis() enables/disables UI menus/tools based on the state
  712. // which the backend is reporting.  If the menu is a check-item, that
  713. // will be reflected into the appropriate item as well.
  714.  
  715. void CComposeFrame::OnUpdateThis ( CCmdUI* pCmdUI, MSG_CommandType tMenuType )
  716. {
  717.    if (!m_pComposePane || !pCmdUI)
  718.       return;
  719.  
  720.     if (GetMsgPane() && MSG_DeliveryInProgress(GetMsgPane())) 
  721.    {
  722.       pCmdUI->Enable(FALSE);
  723.       return;
  724.    }
  725.  
  726.    XP_Bool bSelectable = FALSE;                    // is this a selectable command?
  727.    XP_Bool bPlural = FALSE;                        // indicates whether to append "s" (which we never do)
  728.    MSG_COMMAND_CHECK_STATE sState = MSG_Unchecked; // checked or unchecked 
  729.  
  730.     // call the backend requesting various state information
  731.     MSG_CommandStatus( 
  732.     m_pComposePane, // message pane
  733.         tMenuType,      // MSG_CommandType value
  734.         NULL,           
  735.     0,
  736.         &bSelectable,   // enable/disable
  737.         &sState,        // checked/unchecked
  738.         NULL,
  739.         &bPlural);      // plural command?
  740.  
  741.     pCmdUI->Enable(bSelectable);                // enable or disable item
  742.     pCmdUI->SetCheck(sState == MSG_Checked);    // set the check state
  743.  
  744. }
  745.  
  746. void CComposeFrame::MessageCommand(MSG_CommandType msgCmd)
  747. {
  748.     ASSERT(m_pComposePane);
  749.     MSG_Command(m_pComposePane, msgCmd, NULL, 0);
  750. }
  751.  
  752. void CComposeFrame::OnWrapLongLines ( )
  753. {
  754.    if (!m_bUseHtml)
  755.    {
  756.       int bHasFocus = 0;
  757.       m_bWrapLongLines ^= 1;
  758.       CRect rect;
  759.       CString cs;
  760.  
  761.       if (GetFocus() == (CWnd *)&m_Editor)
  762.           bHasFocus = 1;
  763.  
  764.       m_Editor.GetWindowRect(rect);
  765.       m_EditorParent.ScreenToClient(rect);
  766.       m_Editor.GetWindowText(cs);
  767.       CFont *pFont = m_Editor.GetFont();
  768.  
  769.       m_Editor.DestroyWindow();
  770.       m_Editor.Create ( 
  771.           WS_VSCROLL | ES_MULTILINE | WS_CHILD | WS_VISIBLE | 
  772.               ES_AUTOVSCROLL | ES_WANTRETURN | (m_bWrapLongLines ? 0 : ES_AUTOHSCROLL|WS_HSCROLL),
  773.           rect, &m_EditorParent, IDC_COMPOSEEDITOR);
  774.       
  775.       m_Editor.SetFont(pFont);
  776.       m_Editor.SetWindowText(cs);
  777.  
  778.       if (bHasFocus)
  779.           m_Editor.SetFocus();
  780.    } 
  781. }
  782.  
  783. void CComposeFrame::OnUpdateWrapLongLines ( CCmdUI * pCmdUI )
  784. {
  785.    OnUpdateButtonGeneral(pCmdUI);
  786.    pCmdUI->SetCheck(m_bWrapLongLines == 1);
  787. }
  788.  
  789. void CComposeFrame::OnNew ( )
  790. {
  791.     MSG_Command(GetMsgPane(), MSG_MailNew, NULL, 0);
  792. }
  793.  
  794. void CComposeFrame::OnSelectAll()
  795. {
  796.     if (m_bUseHtml)
  797.         EDT_SelectAll(GetMainContext()->GetContext());
  798.     else
  799.     {
  800.         m_Editor.SetSel(0,-1);
  801.         m_Editor.SetFocus();
  802.     }
  803. }
  804.  
  805. void CComposeFrame::OnUpdateSelectAll(CCmdUI *pCmdUI)
  806. {
  807.     pCmdUI->Enable(TRUE);
  808. }
  809.  
  810. void CComposeFrame::OnUpdatePasteQuote(CCmdUI *pCmdUI)
  811. {
  812.     pCmdUI->Enable(
  813.         IsClipboardFormatAvailable(CF_TEXT)
  814. #ifdef XP_WIN32
  815.             || IsClipboardFormatAvailable(CF_UNICODETEXT)
  816. #endif
  817.     );
  818. }
  819.  
  820. void CComposeFrame::OnPasteQuote( )
  821. {       
  822.     char *lpszText;
  823.     HANDLE hszText;
  824.     char *lpszQuotedText = NULL;
  825.     OpenClipboard();
  826.  
  827. #ifdef XP_WIN32    // ftang
  828.     BOOL bDoneByUnicode = FALSE;
  829.     // Try to use CF_UNICODETEXT first
  830.     if ((CS_USER_DEFINED_ENCODING != (m_iCSID & ~CS_AUTO)) && 
  831.         IsClipboardFormatAvailable(CF_UNICODETEXT) &&
  832.         (hszText = (HANDLE) GetClipboardData(CF_UNICODETEXT)) )
  833.     {
  834.         char* lpszConvertedText = NULL;
  835.         lpszText = (char *) GlobalLock(hszText);
  836.  
  837.         // Now, let's convert the Unicode text into the datacsid encoding
  838.         int ucs2len = CASTINT(INTL_UnicodeLen((INTL_Unicode*)lpszText));
  839.         int    mbbufneeded = CASTINT(INTL_UnicodeToStrLen((m_iCSID & ~CS_AUTO), 
  840.                                                         (INTL_Unicode*)lpszText, 
  841.                                                         ucs2len));
  842.         if(NULL != (lpszConvertedText = (char*)XP_ALLOC(mbbufneeded + 1)))
  843.         {
  844.             INTL_UnicodeToStr(m_iCSID, (INTL_Unicode*)lpszText, ucs2len, 
  845.                                         (unsigned char*) lpszConvertedText, mbbufneeded + 1);
  846.             
  847.             if (m_bUseHtml) {
  848.                 MSG_PastePlaintextQuotation(GetMsgPane(), lpszConvertedText);
  849.             } else {
  850.                 lpszQuotedText = MSG_ConvertToQuotation(lpszConvertedText);
  851.                 FE_InsertMessageCompositionText(GetMainContext()->GetContext(),
  852.                                                 lpszQuotedText, FALSE);
  853.             }
  854.             XP_FREEIF(lpszConvertedText);
  855.  
  856.             bDoneByUnicode = TRUE;
  857.         }
  858.         GlobalUnlock(hszText);
  859.     }
  860.     
  861.     if(bDoneByUnicode)
  862.     {
  863.         // Already done. Do nothing
  864.     }
  865.     else // not done by unicode try CF_TEXT now
  866. #endif
  867.     if (hszText = (HANDLE) GetClipboardData(CF_TEXT)) 
  868.     {
  869.         lpszText = (char *) GlobalLock(hszText);
  870.         if (m_bUseHtml) {
  871.             MSG_PastePlaintextQuotation(GetMsgPane(), lpszText);
  872.         } else {
  873.             lpszQuotedText = MSG_ConvertToQuotation(lpszText);
  874.             FE_InsertMessageCompositionText(GetMainContext()->GetContext(),
  875.                                             lpszQuotedText, FALSE);
  876.         }
  877.         GlobalUnlock(hszText);
  878.     }
  879.     if (lpszQuotedText) XP_FREE(lpszQuotedText);
  880.     CloseClipboard();
  881. }
  882.  
  883. // UpdateToolbar() changes the command IDs as well as the assigned bitmap
  884. // to reflect the current state.. deferred send or immediate delivery.
  885. void CComposeFrame::UpdateToolBar(void)
  886. {
  887.     ApiToolBar(pIToolBar,m_pChrome);
  888.  
  889.     if ( pIToolBar ) 
  890.     {
  891.         pIToolBar->SetButtons(ComposeCodes, sizeof(ComposeCodes) / sizeof(UINT));
  892.         // this is currently loading one bitmap.. this needs to be fixed to add
  893.         // the deferred bitmaps as well.
  894.         pIToolBar->LoadBitmap(MAKEINTRESOURCE(IDB_COMPOSETOOLBAR));
  895.     }
  896. }
  897.  
  898. void CComposeFrame::OnDoneGoingOffline()
  899. {
  900.     BOOL bGlobalDeferred = FALSE;
  901.     PREF_GetBoolPref("network.online", &bGlobalDeferred);
  902.     bSendDeferred = !bGlobalDeferred;
  903.       LPNSTOOLBAR pIToolBar;
  904.     m_pChrome->QueryInterface( IID_INSToolBar, (LPVOID *) &pIToolBar );
  905.  
  906.     if ( pIToolBar ) 
  907.     {
  908.         CString statusStr, toolTipStr, textStr;
  909.         if (bSendDeferred)
  910.         {
  911.             WFE_ParseButtonString(IDM_SENDLATER, statusStr, toolTipStr, textStr);
  912.             CCommandToolbar *pToolBar = (CCommandToolbar *) CWnd::FromHandlePermanent( pIToolBar->GetHWnd() );
  913.             if ( pToolBar)
  914.             {
  915.                 CToolbarButton *pBarButton = pToolBar->GetNthButton(0);
  916.                 if (pBarButton)
  917.                 {
  918.                      pToolBar->ReplaceButtonBitmapIndex(IDM_SENDNOW, 7);
  919.                     pBarButton->SetToolTipText(toolTipStr);
  920.                     pBarButton->SetStatusText(statusStr);
  921.                     pBarButton->SetText(textStr);
  922.                     pBarButton->SetButtonCommand(IDM_SENDLATER);
  923.                 }
  924.                 pIToolBar->Release();
  925.             }
  926.         }
  927.         else
  928.         {
  929.             WFE_ParseButtonString(IDM_SENDNOW, statusStr, toolTipStr, textStr);
  930.             CCommandToolbar *pToolBar = (CCommandToolbar *) CWnd::FromHandlePermanent( pIToolBar->GetHWnd() );
  931.             if (pToolBar)
  932.             {
  933.                 CToolbarButton *pBarButton = pToolBar->GetNthButton(0);
  934.                  pToolBar->ReplaceButtonBitmapIndex(IDM_SENDLATER, 0);
  935.                 if (pBarButton)
  936.                 {
  937.                     pBarButton->SetToolTipText(toolTipStr);
  938.                     pBarButton->SetStatusText(statusStr);
  939.                     pBarButton->SetText(textStr);
  940.                     pBarButton->SetButtonCommand(IDM_SENDNOW);
  941.                 }
  942.                 pIToolBar->Release();
  943.             }
  944.         }
  945.     }
  946. }
  947.  
  948. void CComposeFrame::OnUpdateButtonGeneral(CCmdUI *pCmdUI)    
  949.     OnUpdateThis(pCmdUI, MSG_SendMessage );
  950. }
  951.  
  952. void CComposeFrame::OnUpdateSend(CCmdUI *pCmdUI)
  953. {
  954.     OnUpdateThis(pCmdUI, bSendDeferred ? MSG_SendMessageLater : MSG_SendMessage);
  955.     pCmdUI->SetText(bSendDeferred ? szLoadString(IDS_DEFAULTSENDNOW) : szLoadString(IDS_DEFAULTSENDLATER));
  956. }
  957.  
  958. void CComposeFrame::OnUpdateSendNow(CCmdUI *pCmdUI)
  959. {
  960.  
  961.     OnUpdateThis(pCmdUI, MSG_SendMessage);
  962.     pCmdUI->SetText(bSendDeferred ? szLoadString(IDS_SENDNOW) : szLoadString(IDS_DEFAULTSENDNOW));
  963. }
  964.  
  965. void CComposeFrame::OnUpdateSendLater(CCmdUI *pCmdUI)
  966. {
  967.  
  968.     OnUpdateThis(pCmdUI, MSG_SendMessageLater);
  969.     pCmdUI->SetText(bSendDeferred ? szLoadString(IDS_DEFAULTSENDLATER) : szLoadString(IDS_SENDLATER));
  970. }
  971.  
  972. // This function is send to the backend for a callback when quoting
  973. // text. Currently, it simply calls the pre-existing insert code.
  974. int WFE_InsertMessage(void *closure, const char * data)
  975. {
  976.    if (data) {
  977.       FE_InsertMessageCompositionText((MWContext*)closure,data,FALSE);
  978.    }
  979.    else {
  980.        MSG_Pane *pPane = MSG_FindPane((MWContext *)closure, MSG_COMPOSITIONPANE);
  981.        if (pPane) {
  982.             CComposeFrame * pCompose = (CComposeFrame *) MSG_GetFEData(pPane);
  983.             if (pCompose->GetQuoteSel() != -1) {
  984.                 if (! pCompose->UseHtml()) {
  985.                     int32 eReplyOnTop = 0;
  986.                     int start = ((int) pCompose->GetQuoteSel()), end = start;
  987.                     int tmpStart = 0;
  988.  
  989.                     if (PREF_NOERROR ==
  990.                             PREF_GetIntPref("mailnews.reply_on_top", &eReplyOnTop)) {
  991.                         switch(eReplyOnTop) {
  992.                         case 1:
  993.                         default:
  994.                             pCompose->GetEditor()->SetSel(start, end);
  995.                             break;
  996.                         case 2:
  997.                             pCompose->GetEditor()->GetSel(tmpStart, end);
  998.                             pCompose->GetEditor()->SetSel(start, end);
  999.                             break;
  1000.                         case 3:
  1001.                             pCompose->GetEditor()->GetSel(tmpStart, end);
  1002.                             pCompose->GetEditor()->SetSel(end, start);
  1003.                             break;
  1004.                         }
  1005.                     }
  1006.                 }
  1007.                 pCompose->SetQuoteSel(-1);
  1008.             }
  1009.        }
  1010.    }
  1011.    return 0;
  1012. }
  1013.  
  1014. void CComposeFrame::OnQuoteOriginal( void )
  1015. {
  1016.     SetQuoteSelection();
  1017.     MSG_QuoteMessage(GetMsgPane(),WFE_InsertMessage,(void*)GetMainContext()->GetContext());
  1018. }
  1019.  
  1020. void CComposeFrame::OnAddressTab(void)
  1021. {
  1022.     m_pComposeBar->OnAddressTab();
  1023. }
  1024.  
  1025. void CComposeFrame::OnAttachTab(void)
  1026. {
  1027.     m_pComposeBar->OnAttachTab();
  1028. }
  1029.  
  1030. void CComposeFrame::OnOptionsTab(void)
  1031. {
  1032.     m_pComposeBar->OnOptionsTab();
  1033. }
  1034.  
  1035. void CComposeFrame::OnCollapse(void)
  1036. {
  1037.     m_pComposeBar->OnCollapse();
  1038. }
  1039.  
  1040. // OnSaveAs().. This should probably have better backend support.  This function
  1041. // gets the current message body text and saves it to a user specified location.
  1042.  
  1043. void CComposeFrame::OnSaveAs(void)
  1044. {
  1045.     // Call the file-picker to get a filename/location.
  1046.     char * pPath = wfe_GetSaveFileName(m_hWnd, XP_GetString(MK_MSG_SAVE_AS), szLoadString(IDS_DEFAULTSAVEAS), 0);
  1047.     
  1048.     // if a valid path was specified, continue with save
  1049.     if (pPath && strlen(pPath)) 
  1050.     {
  1051.         uint32 ulBodySize;
  1052.         char *pBody;
  1053.     
  1054.     // open the file for writing
  1055.         FILE *pFile = fopen(pPath, "w");
  1056.     
  1057.     // if the file was opened successfully, continue with save
  1058.         if (pFile)
  1059.     {
  1060.             FE_GetMessageBody(m_pComposePane, &pBody, &ulBodySize, NULL);
  1061.             if (!fwrite(pBody, sizeof(char), CASTSIZE_T(ulBodySize), pFile)) 
  1062.         {
  1063.         // couldn't write file
  1064.                 char szOpenError[512];
  1065.                 sprintf(szOpenError, szLoadString(IDS_CANTWRITETOFILE), pPath);
  1066.                 FE_Alert(GetMainContext()->GetContext(), szOpenError);
  1067.             }
  1068.             if (UseHtml())
  1069.                 XP_HUGE_FREE(pBody);
  1070.             else
  1071.                 XP_FREE(pBody); 
  1072.             fclose(pFile);
  1073.         } 
  1074.     else 
  1075.     {
  1076.         // can't open file
  1077.             char szOpenError[512];
  1078.             sprintf(szOpenError, szLoadString(IDS_CANTWRITETOFILE), pPath);
  1079.             FE_Alert(GetMainContext()->GetContext(), szOpenError);
  1080.         }
  1081.         XP_FREE(pPath);
  1082.     }
  1083. }
  1084.  
  1085.  
  1086. void CComposeFrame::OnCheckSpelling()
  1087. {
  1088.    CWnd * pWnd = GetEditorWnd();
  1089.    if (pWnd)
  1090.       pWnd->SendMessage(WM_COMMAND,ID_CHECK_SPELLING);
  1091. }
  1092.  
  1093. // OnSaveAsDraft() sends based on the current delivery state.
  1094.  
  1095. void CComposeFrame::OnSaveDraft ( void )
  1096.  
  1097. {
  1098.     ASSERT(m_pComposeBar);
  1099.     m_pComposeBar->UpdateHeaderInfo ( );
  1100.  
  1101.     // first we must get the text from the front end and then
  1102.     // tell the backend what text to send.
  1103.  
  1104.     uint32 ulBodySize;
  1105.     char *pBody;
  1106.  
  1107.     FE_GetMessageBody(GetMsgPane(), &pBody, &ulBodySize, NULL);
  1108.     
  1109.     // if we could get text, tell the backend
  1110.     if (ulBodySize) 
  1111.     MSG_SetCompBody(GetMsgPane(),pBody);
  1112.  
  1113.     // start the meteors tumbling    
  1114.     GetChrome()->StartAnimation();
  1115.  
  1116.     MWContext *context;
  1117.     context = GetMainContext()->GetContext();
  1118.  
  1119.     // Pass current csid to backend, so it can do right conversion for 
  1120.     // 8bit header.    
  1121.     INTL_SetCSIDocCSID(LO_GetDocumentCharacterSetInfo(context), m_iCSID);
  1122.  
  1123.     MSG_Command(GetMsgPane(), MSG_SaveDraft, 0, 0);
  1124.     
  1125.     GetChrome()->StopAnimation();
  1126.  
  1127.     if (!m_bUseHtml)
  1128.         m_EditorParent.m_bModified = FALSE;
  1129. }
  1130.  
  1131.  
  1132.  
  1133. void CComposeFrame::OnUpdateSaveDraft(CCmdUI *pCmdUI)
  1134. {
  1135.  
  1136.     // Change the string based on the deferred sending status
  1137.  
  1138.     OnUpdateThis(pCmdUI, MSG_SaveDraft );
  1139.  
  1140. }
  1141.  
  1142.  
  1143. void CComposeFrame::OnSaveTemplate ( void )
  1144.  
  1145. {
  1146.     ASSERT(m_pComposeBar);
  1147.     m_pComposeBar->UpdateHeaderInfo ( );
  1148.  
  1149.     // first we must get the text from the front end and then
  1150.     // tell the backend what text to send.
  1151.  
  1152.     uint32 ulBodySize;
  1153.     char *pBody;
  1154.  
  1155.     FE_GetMessageBody(GetMsgPane(), &pBody, &ulBodySize, NULL);
  1156.     
  1157.     // if we could get text, tell the backend
  1158.     if (ulBodySize) 
  1159.     MSG_SetCompBody(GetMsgPane(),pBody);
  1160.  
  1161.     // start the meteors tumbling    
  1162.     GetChrome()->StartAnimation();
  1163.  
  1164.     MWContext *context;
  1165.     context = GetMainContext()->GetContext();
  1166.  
  1167.     // Pass current csid to backend, so it can do right conversion for 
  1168.     // 8bit header.    
  1169.     INTL_SetCSIDocCSID(LO_GetDocumentCharacterSetInfo(context), m_iCSID);
  1170.  
  1171.     MSG_Command(GetMsgPane(), MSG_SaveTemplate, 0, 0);
  1172.     
  1173.     GetChrome()->StopAnimation();
  1174.  
  1175.     if (!m_bUseHtml)
  1176.         m_EditorParent.m_bModified = FALSE;
  1177. }
  1178.  
  1179. void CComposeFrame::OnUpdateSaveTemplate(CCmdUI *pCmdUI)
  1180. {
  1181.  
  1182.     // Change the string based on the deferred sending status
  1183.  
  1184.     OnUpdateThis(pCmdUI, MSG_SaveTemplate );
  1185.  
  1186. }
  1187.  
  1188.  
  1189. LRESULT CComposeFrame::OnButtonMenuOpen(WPARAM wParam, LPARAM lParam)
  1190. {
  1191.     HMENU hMenu = (HMENU) lParam;
  1192.     UINT nCommand = (UINT) LOWORD(wParam);
  1193.     if (nCommand == IDM_ATTACHFILE){
  1194.         ::AppendMenu(hMenu,MF_STRING|MF_ENABLED, IDM_ATTACHFILE, szLoadString(IDS_TOOLATTACHFILE));
  1195.         ::AppendMenu(hMenu,MF_STRING|MF_ENABLED, IDM_ATTACHWEBPAGE, szLoadString(IDS_ATTACHWEBPAGE));
  1196.         ::AppendMenu(hMenu,MF_SEPARATOR, 0, NULL);
  1197.         ::AppendMenu(hMenu,MF_STRING|MF_ENABLED, IDM_ATTACHMYCARD, szLoadString(IDS_ATTACHMYCARD));
  1198.         return 1;
  1199.     } else if (GetMainWinContext()){
  1200.         // Route other messages to Edit View, which handles messages common to all Composer frames
  1201.         return ::SendMessage( GetMainWinContext()->GetPane(), NSBUTTONMENUOPEN, wParam, lParam);
  1202.     }
  1203.     return 0;
  1204. }
  1205.  
  1206. // DoSend() sends based on the current delivery state.
  1207. void CComposeFrame::DoSend ( BOOL bNow )
  1208. {
  1209.     ASSERT(m_pComposeBar);
  1210.     LPADDRESSCONTROL pIAddress = GetAddressWidgetInterface();
  1211.     if (pIAddress)
  1212.     {
  1213.         CListBox * pListBox = pIAddress->GetListBox();
  1214.         if (::IsWindow(pListBox->m_hWnd))
  1215.             pListBox->SendMessage(WM_NOTIFYSELECTIONCHANGE);
  1216.     }
  1217.     MSG_ClearComposeHeaders(GetMsgPane());
  1218.     m_pComposeBar->UpdateHeaderInfo ( );
  1219.  
  1220.     // first we must get the text from the front end and then
  1221.     // tell the backend what text to send.
  1222.     uint32 ulBodySize;
  1223.     char *pBody = NULL;
  1224.     FE_GetMessageBody(GetMsgPane(), &pBody, &ulBodySize, NULL);
  1225.     
  1226. #ifndef _WIN32
  1227.     if (ulBodySize > 32767) {
  1228.         MessageBox(szLoadString(IDS_MSGTOBIG), szLoadString(IDS_TITLE_ERROR), MB_ICONSTOP|MB_OK);
  1229.         return;
  1230.     }
  1231. #endif
  1232.     // if we could get text, tell the backend
  1233.     if (pBody) 
  1234.         MSG_SetCompBody(GetMsgPane(),pBody);
  1235.  
  1236.     int errcode = 0;
  1237.     MWContext * context = GetMainContext()->GetContext();
  1238.     while ((errcode = MSG_SanityCheck(GetMsgPane(),errcode))!=0)
  1239.     {
  1240.         GetChrome()->StopAnimation();
  1241.         if (errcode == MK_MSG_MISSING_SUBJECT)
  1242.         {
  1243.             char * ptr = PromptMessageSubject();
  1244.             if (ptr != NULL)
  1245.             {
  1246.                 MSG_SetCompHeader(GetMsgPane(),MSG_SUBJECT_HEADER_MASK,ptr);
  1247.                 XP_FREE(ptr);
  1248.             }
  1249.             else
  1250.                 return;
  1251.         }
  1252.         else if (!FE_Confirm(context,XP_GetString(errcode)))
  1253.             return;
  1254.     }
  1255.     
  1256.     // Pass current csid to backend, so it can do right conversion for 
  1257.     // 8bit header.  
  1258.     INTL_SetCSIWinCSID(LO_GetDocumentCharacterSetInfo(context), m_iCSID);
  1259.    
  1260.     MSG_Command(GetMsgPane(), bNow ? MSG_SendMessage : MSG_SendMessageLater, 0, 0);
  1261.  
  1262.     if (GetMsgPane() && MSG_DeliveryInProgress(GetMsgPane())) {
  1263.         // start the meteors tumbling    
  1264.         GetChrome()->StartAnimation();
  1265.         LPNSSTATUSBAR pIStatusBar = NULL;
  1266.         GetChrome()->QueryInterface( IID_INSStatusBar, (LPVOID *) &pIStatusBar );
  1267.         if ( pIStatusBar ) {
  1268.             pIStatusBar->ModalStatus( TRUE, 0, szLoadString(IDS_SENDINGMESSAGE));
  1269.             pIStatusBar->Release();
  1270.         }
  1271.     }
  1272.   // rhp - this condition is for MAPI UI-less send operations...
  1273.   else
  1274.   {
  1275.     if (!IsWindowVisible())       // First, check if the window is not already visible
  1276.       ShowWindow(SW_SHOW);        // and if not, get it on the screen for the user to deal with...    
  1277.   }
  1278.   // rhp 
  1279. }
  1280.  
  1281. void CComposeFrame::OnAttachMyCard()
  1282. {
  1283.     ASSERT(m_pComposeBar);
  1284.     m_pComposeBar->SetAttachMyCard(!m_pComposeBar->GetAttachMyCard());
  1285. }
  1286.  
  1287. void CComposeFrame::OnUpdateAttachMyCard(CCmdUI * pCmdUI)
  1288. {
  1289.     pCmdUI->Enable(TRUE);
  1290.     pCmdUI->SetCheck(m_pComposeBar->GetAttachMyCard());
  1291. }
  1292.  
  1293. void CComposeFrame::OnAttachFile()
  1294. {
  1295.     ASSERT(m_pComposeBar);
  1296.     m_pComposeBar->OnAttachTab();
  1297.     m_pComposeBar->UpdateWindow();
  1298.     m_pComposeBar->AttachFile();
  1299. }
  1300.  
  1301. void CComposeFrame::OnAttachUrl()
  1302. {
  1303.     ASSERT(m_pComposeBar);
  1304.     m_pComposeBar->OnAttachTab();
  1305.     m_pComposeBar->UpdateWindow();
  1306.     m_pComposeBar->AttachUrl();
  1307. }
  1308.  
  1309. void CComposeFrame::ConvertToPlainText()
  1310. {
  1311.    if (MessageBox(szLoadString(IDS_CONVERTWARN), szLoadString(IDS_CONVERTTITLE), 
  1312.       MB_ICONEXCLAMATION | MB_YESNO) == IDYES)
  1313.    {
  1314.  
  1315.       MWContext *pMWContext;
  1316.       if( GetMainContext() == NULL ||
  1317.          (pMWContext = GetMainContext()->GetContext()) == NULL )
  1318.              return;
  1319.         // Stop any active plugin
  1320.       if (!CheckAndCloseEditorPlugin(pMWContext)) 
  1321.          return;
  1322.       EDT_DestroyEditBuffer(pMWContext);
  1323.       pMWContext->is_editor = FALSE;
  1324.       m_pChrome->SetMenu(IDR_COMPOSEPLAIN);
  1325.       DestroyHtmlToolbars();
  1326.       RecalcLayout();
  1327.       CreatePlainTextEditor();
  1328.       ::SendMessage(m_Editor.GetSafeHwnd(), WM_SETFONT, (WPARAM)m_cfTextFont, FALSE);
  1329.       m_bUseHtml = FALSE;
  1330.    }
  1331. }
  1332.  
  1333. void CComposeFrame::ConvertToHtml()
  1334. {
  1335.    m_pChrome->SetMenu(IDR_COMPOSEFRAME);
  1336.    CreateHtmlToolbars();
  1337.    ShowHtmlToolbars();
  1338.    RecalcLayout();
  1339.    SetEditorParent(NULL);
  1340.    m_Editor.DestroyWindow();
  1341.    m_EditorParent.DestroyWindow();
  1342.    m_bUseHtml = TRUE;
  1343.  
  1344.    if (GetMainContext() != NULL)
  1345.    {
  1346.       CWinCX * pWinCX = GetMainContext()->IsFrameContext() ? 
  1347.          VOID2CX(GetMainContext(),CWinCX) : NULL;
  1348.       if (pWinCX != NULL)
  1349.       {
  1350.          MWContext * pContext = pWinCX->GetContext();
  1351.          if (!pContext->is_editor)
  1352.          {
  1353.             pContext->is_editor = TRUE;
  1354.             URL_Struct * pUrl = NET_CreateURLStruct(EDT_NEW_DOC_URL,NET_DONT_RELOAD);
  1355.             if (pUrl != NULL)
  1356.             {
  1357.                pWinCX->GetUrl(pUrl, FO_CACHE_AND_PRESENT);
  1358.                pWinCX->GetContext()->bIsComposeWindow = TRUE;
  1359.             }
  1360.          }  
  1361.       }
  1362.    }
  1363. }
  1364.  
  1365. void CComposeFrame::OnConvert()
  1366. {
  1367.    if (m_bUseHtml)   
  1368.       ConvertToPlainText();
  1369.    else
  1370.       ConvertToHtml();   
  1371. }
  1372.  
  1373. void CComposeFrame::OnUpdateConvert(CCmdUI * pCmdUI)
  1374. {
  1375.    pCmdUI->Enable(FALSE);   // wait for it
  1376. }
  1377.  
  1378. void CComposeFrame::OnSend()
  1379. {
  1380.     DoSend(!bSendDeferred);
  1381. }
  1382.  
  1383. void CComposeFrame::OnSendNow()
  1384. {
  1385.    DoSend(TRUE );
  1386. }
  1387.  
  1388. void CComposeFrame::OnSendLater()
  1389. {
  1390.    DoSend(FALSE);
  1391. }
  1392.  
  1393. void CComposeFrame::MakeComposeBarVisible()
  1394. {
  1395.     if (!GetComposeBar()->IsVisible())
  1396.         GetComposeBar()->OnToggleShow();
  1397.     else if (GetComposeBar()->IsCollapsed())
  1398.     {
  1399.         GetComposeBar()->OnCollapse();
  1400.         CCustToolbar * pToolbar = GetChrome()->GetCustomizableToolbar();
  1401.         if( pToolbar ) 
  1402.             pToolbar->RemoveExternalTab(1);
  1403.            RecalcLayout();
  1404.     }
  1405. }
  1406.  
  1407. void CComposeFrame::OnViewAddresses()
  1408. {
  1409.     MakeComposeBarVisible();
  1410.     GetComposeBar()->SendMessage(WM_COMMAND,IDC_ADDRESSTAB);
  1411. }
  1412.  
  1413. void CComposeFrame::OnViewAttachments()
  1414. {
  1415.     MakeComposeBarVisible();
  1416.     m_pComposeBar->m_pSubjectEdit->SetFocus();
  1417.     UpdateWindow();
  1418.     GetComposeBar()->SendMessage(WM_COMMAND,IDC_ATTACHTAB);
  1419. }
  1420.  
  1421. void CComposeFrame::OnViewOptions()
  1422. {
  1423.     MakeComposeBarVisible();
  1424.     m_pComposeBar->m_pSubjectEdit->SetFocus();
  1425.     UpdateWindow();
  1426.     GetComposeBar()->PostMessage(WM_COMMAND,IDC_OPTIONSTAB);
  1427. }
  1428.  
  1429. void CComposeFrame::OnUpdateViewAddresses(CCmdUI * pCmdUI)
  1430. {
  1431.     pCmdUI->SetRadio(GetComposeBar()->GetTab() == IDX_COMPOSEADDRESS);
  1432.     pCmdUI->Enable(TRUE);
  1433. }
  1434.  
  1435. void CComposeFrame::OnUpdateViewAttachments(CCmdUI * pCmdUI)
  1436. {
  1437.     pCmdUI->SetRadio(GetComposeBar()->GetTab() == IDX_COMPOSEATTACH);
  1438.     pCmdUI->Enable(TRUE);
  1439. }
  1440.  
  1441. void CComposeFrame::OnUpdateViewOptions(CCmdUI * pCmdUI)
  1442. {
  1443.     pCmdUI->SetRadio(GetComposeBar()->GetTab() == IDX_COMPOSEOPTIONS);
  1444.     pCmdUI->Enable(TRUE);
  1445. }
  1446.  
  1447. // OnSetInitialFocus - Invoked after the frame window, toolbar and view are created.
  1448. // It sets the initial keyboard focus.
  1449.  
  1450. LONG CComposeFrame::OnSetInitialFocus(WPARAM wParam, LPARAM lParam)
  1451. {
  1452.     return 0;
  1453. }
  1454.  
  1455. void CComposeFrame::SetInitialText( const char *pText )
  1456. {
  1457.     if (m_pInitialText)
  1458.         XP_FREE (m_pInitialText);
  1459.  
  1460.     m_pInitialText = NULL;
  1461.  
  1462.     if (pText)
  1463.         m_pInitialText = XP_STRDUP(pText);
  1464. }
  1465.  
  1466. BOOL CComposeFrame::BccOnly(void)
  1467. {
  1468.     LPADDRESSCONTROL pIAddress = GetAddressWidgetInterface();
  1469.     CListBox * pListBox = pIAddress->GetListBox();
  1470.     int count = pListBox->GetCount();
  1471.     int total = 0;
  1472.     for (int i=0; i<count; i++)
  1473.     {
  1474.         char * szName, * szType;
  1475.         if(pIAddress->GetEntry(i,&szType, &szName))
  1476.             if(strcmp(szType,szLoadString(IDS_ADDRESSBCC)))
  1477.                 total++;
  1478.     }
  1479.     return !total;
  1480. }
  1481.  
  1482. void CComposeFrame::InsertInitialText(void)
  1483. {
  1484.     const char *pBody = MSG_GetCompBody(GetMsgPane());
  1485.  
  1486.     LPADDRESSCONTROL pIAddress = GetAddressWidgetInterface();
  1487.     if (pIAddress)
  1488.     {
  1489.         CListBox * pListBox = pIAddress->GetListBox();
  1490.         if (::IsWindow(pListBox->m_hWnd))
  1491.             pListBox->ResetContent();
  1492.     }
  1493.  
  1494.     if (m_pInitialText && strlen(m_pInitialText))
  1495.     {
  1496.         EDT_ReadFromBuffer(GetMainContext()->GetContext(),
  1497.                         m_pInitialText);
  1498.         XP_FREEIF(m_pInitialText);
  1499.     }
  1500.     else if (pBody && strlen(pBody))
  1501.     {
  1502.         FE_InsertMessageCompositionText( GetMainContext()->GetContext(), pBody, TRUE);
  1503.         FE_InsertMessageCompositionText( GetMainContext()->GetContext(), "\n", TRUE);
  1504.         MSG_SetCompBody(GetMsgPane(), "");
  1505.     }
  1506.  
  1507.     CompleteComposeInitialization();
  1508.     if (m_bUseHtml)
  1509.         EDT_SetDirtyFlag(GetMainContext()->GetContext(), FALSE);
  1510.  
  1511.     if (MSG_ShouldAutoQuote(GetMsgPane()))
  1512.     {
  1513.         SetQuoteSelection();
  1514.         MSG_QuoteMessage(GetMsgPane(),WFE_InsertMessage,(void*)GetMainContext()->GetContext());
  1515.     }
  1516. }
  1517.  
  1518. void CComposeFrame::CompleteComposeInitialization(void)
  1519. {
  1520.     MSG_HeaderEntry * entry;
  1521.     int nCount;
  1522.     nCount = MSG_RetrieveStandardHeaders(GetMsgPane(),&entry);
  1523.     LPADDRESSCONTROL pIAddress = m_pComposeBar->GetAddressWidgetInterface();
  1524.     CListBox * pListBox = pIAddress->GetListBox();
  1525.     if (nCount > 0) 
  1526.     {
  1527.         int i;
  1528.         pListBox->LockWindowUpdate();
  1529.         for (i=0; i<nCount; i++)
  1530.         {
  1531.             pIAddress->AppendEntry(FALSE,
  1532.                 MSG_HeaderMaskToString(entry[i].header_type),
  1533.                 entry[i].header_value,
  1534.                 0, 0);
  1535.             XP_FREE(entry[i].header_value);
  1536.         }
  1537.         pIAddress->AppendEntry();
  1538.         ::LockWindowUpdate(NULL);
  1539.     }
  1540.  
  1541.     if (entry)
  1542.         XP_FREE(entry);
  1543.  
  1544.     const char * subject = MSG_GetCompHeader(GetMsgPane(),MSG_SUBJECT_HEADER_MASK);
  1545.  
  1546.     if (!nCount)
  1547.         pIAddress->AppendEntry(NULL);
  1548.  
  1549.     // in case of the existance hidden headers, get new count
  1550.     nCount = pListBox->GetCount();
  1551.  
  1552.     if (subject && strlen(subject))
  1553.     {
  1554.         m_pComposeBar->m_pSubjectEdit->SetWindowText(subject);
  1555.         GetChrome()->SetDocumentTitle(subject);
  1556.     }
  1557.  
  1558.     if (nCount<=1 || BccOnly())  
  1559.     {
  1560.         if (BccOnly())
  1561.         {
  1562.             pIAddress->DeleteEntry(pListBox->GetCount()-1);
  1563.             pIAddress->AppendEntry(TRUE, szLoadString(IDS_ADDRESSTO),"",0,0);
  1564.         }
  1565.         pListBox->UpdateWindow();
  1566.         pListBox->SetFocus();
  1567.         SetFocusField(pListBox);
  1568.     }
  1569.     else if (subject && strlen(subject))
  1570.     {
  1571.         if (!UseHtml())
  1572.         {
  1573.             GetEditor()->SetFocus();
  1574.             SetFocusField(GetEditor());
  1575.         }
  1576.     }
  1577.     else
  1578.     {
  1579.         m_pComposeBar->m_pSubjectEdit->SetSel(-1,0);
  1580.         m_pComposeBar->m_pSubjectEdit->SetFocus();
  1581.         SetFocusField(m_pComposeBar->m_pSubjectEdit);
  1582.     }
  1583.  
  1584.    // Set the message priority based on the fileds
  1585.     const char * priorityString = MSG_GetCompHeader(GetMsgPane(), MSG_PRIORITY_HEADER_MASK);
  1586.     if (priorityString) 
  1587.     {
  1588.         // Backend deals only untranslated priority; we have to do some mapping here
  1589.         if (strstr(priorityString, "Highest"))
  1590.             m_pComposeBar->m_iPriorityIdx = MSG_HighestPriority - 2;
  1591.         else if (strstr(priorityString, "High"))
  1592.             m_pComposeBar->m_iPriorityIdx = MSG_HighPriority - 2;
  1593.         else if (strstr(priorityString, "Lowest"))
  1594.             m_pComposeBar->m_iPriorityIdx = MSG_LowestPriority - 2;
  1595.         else if (strstr(priorityString, "Low"))
  1596.             m_pComposeBar->m_iPriorityIdx = MSG_LowPriority - 2;
  1597.         else 
  1598.             m_pComposeBar->m_iPriorityIdx = MSG_NormalPriority - 2;
  1599.     }
  1600.  
  1601.     switch (MSG_GetHTMLAction(GetMsgPane())) {
  1602.         default:
  1603.         case MSG_HTMLAskUser:
  1604.             m_pComposeBar->m_pszMessageFormat = strdup(szLoadString(IDS_FORMAT_ASKME));
  1605.             break;
  1606.         case MSG_HTMLUseMultipartAlternative:
  1607.             m_pComposeBar->m_pszMessageFormat = strdup(szLoadString(IDS_FORMAT_BOTH));
  1608.             break;
  1609.         case MSG_HTMLConvertToPlaintext:
  1610.             m_pComposeBar->m_pszMessageFormat = strdup(szLoadString(IDS_FORMAT_PLAIN));
  1611.             break;
  1612.         case MSG_HTMLSendAsHTML:
  1613.             m_pComposeBar->m_pszMessageFormat = strdup(szLoadString(IDS_FORMAT_HTML));
  1614.             break;
  1615.     }
  1616.  
  1617.     m_pComposeBar->SetAttachMyCard(MSG_GetCompBoolHeader(GetMsgPane(),MSG_ATTACH_VCARD_BOOL_HEADER_MASK));
  1618.     m_pComposeBar->SetReturnReceipt(MSG_GetCompBoolHeader(GetMsgPane(),MSG_RETURN_RECEIPT_BOOL_HEADER_MASK));
  1619.     m_pComposeBar->SetUseUUENCODE(MSG_GetCompBoolHeader(GetMsgPane(),MSG_UUENCODE_BINARY_BOOL_HEADER_MASK));
  1620.     UpdateSecurityOptions();
  1621.  
  1622.     m_bInitialized = TRUE;
  1623. }
  1624.  
  1625. void CComposeFrame::UpdateSecurityOptions(void)
  1626. {
  1627.     m_pComposeBar->SetSigned(MSG_GetCompBoolHeader(GetMsgPane(),MSG_SIGNED_BOOL_HEADER_MASK));
  1628.     m_pComposeBar->SetEncrypted(MSG_GetCompBoolHeader(GetMsgPane(),MSG_ENCRYPTED_BOOL_HEADER_MASK));
  1629. }
  1630.  
  1631. void CComposeFrame::GoldDoneLoading ()
  1632. {
  1633.    MSG_InitializeCompositionPane(GetMsgPane(),m_pOldContext,m_pFields);
  1634.    PostMessage(WM_COMP_SET_INITIAL_FOCUS);
  1635.    UpdateAttachmentInfo();
  1636. }
  1637.  
  1638. ////////////////////////////////////////////////////////////////////////////////////
  1639. // Begin the pseudo-backend code here.
  1640.  
  1641. const char * MSG_HeaderMaskToString(MSG_HEADER_SET header)
  1642. {
  1643.     const char * retval = NULL;
  1644.     switch (header)
  1645.     {
  1646.         case MSG_TO_HEADER_MASK:
  1647.             retval = szLoadString(IDS_ADDRESSTO);
  1648.             break;
  1649.         case MSG_CC_HEADER_MASK:
  1650.             retval = szLoadString(IDS_ADDRESSCC);
  1651.             break;
  1652.         case MSG_BCC_HEADER_MASK:
  1653.             retval = szLoadString(IDS_ADDRESSBCC);
  1654.             break;
  1655.         case MSG_REPLY_TO_HEADER_MASK:
  1656.             retval = szLoadString(IDS_ADDRESSREPLYTO);
  1657.             break;
  1658.         case MSG_NEWSGROUPS_HEADER_MASK:
  1659.             retval = szLoadString(IDS_ADDRESSNEWSGROUP);
  1660.             break;
  1661.         case MSG_FOLLOWUP_TO_HEADER_MASK:
  1662.             retval = szLoadString(IDS_ADDRESSFOLLOWUPTO);
  1663.             break;
  1664.         default:
  1665.             XP_ASSERT(0);
  1666.     }
  1667.     return retval;
  1668. }
  1669.  
  1670. MSG_HEADER_SET MSG_StringToHeaderMask(char * string)
  1671. {
  1672.     MSG_HEADER_SET retval = 0;
  1673.     if (!stricmp(szLoadString(IDS_ADDRESSTO),string))
  1674.         retval = MSG_TO_HEADER_MASK;
  1675.     else if (!stricmp(szLoadString(IDS_ADDRESSCC),string))
  1676.         retval = MSG_CC_HEADER_MASK;
  1677.     else if (!stricmp(szLoadString(IDS_ADDRESSBCC),string))
  1678.         retval = MSG_BCC_HEADER_MASK;
  1679.     else if (!stricmp(szLoadString(IDS_ADDRESSREPLYTO),string))
  1680.         retval = MSG_REPLY_TO_HEADER_MASK;
  1681.     else if (!stricmp(szLoadString(IDS_ADDRESSNEWSGROUP),string))
  1682.         retval = MSG_NEWSGROUPS_HEADER_MASK;
  1683.     else if (!stricmp(szLoadString(IDS_ADDRESSFOLLOWUPTO),string))
  1684.         retval = MSG_FOLLOWUP_TO_HEADER_MASK;
  1685.     else
  1686.         XP_ASSERT(0);
  1687.     return retval;
  1688. }
  1689.  
  1690. BOOL CComposeFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
  1691. {
  1692.    BOOL bRetVal = CGenericFrame::OnCmdMsg(nID,nCode,pExtra,pHandlerInfo);
  1693.    if (nCode == CN_UPDATE_COMMAND_UI)
  1694.       if (!bRetVal && !m_bUseHtml)
  1695.          bRetVal = m_Editor.OnCmdMsg(nID,nCode,pExtra,pHandlerInfo);
  1696.    return bRetVal;
  1697. }
  1698.  
  1699. void CComposeFrame::OnToggleMessageToolbar()
  1700. {
  1701.     GetChrome()->ShowToolbar(ID_COMPOSE_MESSAGE_TOOLBAR, !GetChrome()->GetToolbarVisible(ID_COMPOSE_MESSAGE_TOOLBAR));
  1702. }
  1703.  
  1704. void CComposeFrame::OnUpdateToggleMessageToolbar(CCmdUI* pCmdUI)
  1705. {
  1706.    if( pCmdUI->m_pMenu ){
  1707.       pCmdUI->m_pMenu->ModifyMenu(IDM_OPT_MESSAGEBAR_TOGGLE, MF_BYCOMMAND | MF_STRING, CASTUINT(IDM_OPT_MESSAGEBAR_TOGGLE),
  1708.                                   szLoadString(GetChrome()->GetToolbarVisible(ID_COMPOSE_MESSAGE_TOOLBAR) ?
  1709.                                                IDS_HIDE_MESSAGE_TOOLBAR : IDS_SHOW_MESSAGE_TOOLBAR ) );
  1710.    }   
  1711.    pCmdUI->Enable(TRUE);
  1712. }
  1713.  
  1714. void CComposeFrame::OnToggleAddressArea()
  1715. {
  1716.     m_pComposeBar->OnToggleShow();
  1717. }
  1718.  
  1719. void CComposeFrame::OnUpdateToggleAddressArea(CCmdUI * pCmdUI)
  1720. {
  1721.    //CLM: Change to a Show|Hide pair of strings
  1722.    if( pCmdUI->m_pMenu ){
  1723.       pCmdUI->m_pMenu->ModifyMenu(IDM_MESSAGEBODYONLY, MF_BYCOMMAND | MF_STRING, CASTUINT(IDM_MESSAGEBODYONLY),
  1724.                                   szLoadString(CASTUINT(m_pComposeBar->IsVisible() ?
  1725.                                                IDS_HIDE_ADDRESS_AREA : IDS_SHOW_ADDRESS_AREA)) );
  1726.    }   
  1727.    pCmdUI->Enable(TRUE);
  1728. }
  1729.  
  1730. #define UNSECURE_INDEX        9
  1731. #define SECURE_INDEX        11
  1732. #define UNSEC_SIGNED_INDEX    8
  1733. #define SEC_SIGNED_INDEX    10
  1734.  
  1735. void CComposeFrame::OnUpdateSecurity(CCmdUI * pCmdUI)
  1736. {
  1737.     XP_Bool bSigned = m_pComposeBar->GetSigned();
  1738.     XP_Bool bEncrypted = m_pComposeBar->GetEncrypted();
  1739.     LPNSTOOLBAR pIToolBar;
  1740.     m_pChrome->QueryInterface( IID_INSToolBar, (LPVOID *) &pIToolBar );
  1741.     if ( pIToolBar ) {
  1742.         CCommandToolbar *pToolBar = (CCommandToolbar *) CWnd::FromHandlePermanent( pIToolBar->GetHWnd() );
  1743.         
  1744.         int index = bEncrypted ? 
  1745.                     (bSigned ? SEC_SIGNED_INDEX : SECURE_INDEX) :
  1746.                     (bSigned ? UNSEC_SIGNED_INDEX : UNSECURE_INDEX);
  1747.  
  1748.         pToolBar->ReplaceButtonBitmapIndex(ID_SECURITY, index);
  1749.         pIToolBar->Release();
  1750.     }
  1751.    OnUpdateButtonGeneral(pCmdUI);
  1752. }
  1753.  
  1754. void CComposeFrame::OnUpdateSecureStatus(CCmdUI *pCmdUI)
  1755. {
  1756.     XP_Bool bSigned = m_pComposeBar->GetSigned();
  1757.     XP_Bool bEncrypted = m_pComposeBar->GetEncrypted();
  1758.  
  1759.     if (pCmdUI->m_nID == IDS_SECURITY_STATUS)
  1760.         pCmdUI->Enable(bEncrypted);
  1761.     else
  1762.         pCmdUI->Enable(bSigned);
  1763. }
  1764.  
  1765. char * CComposeFrame::PromptMessageSubject()
  1766. {
  1767.     CWnd * pWnd = GetFocus();
  1768.     CString csText;
  1769.     CString csDefault;
  1770.     csText.LoadString(IDS_COMPOSE_NOSUBJECT);
  1771.     csDefault.LoadString(IDS_COMPOSE_DEFAULTNOSUBJECT);
  1772.     MWContext * pContext = GetMainContext()->GetContext();
  1773.     char * ptr = ABSTRACTCX(pContext)->Prompt(pContext, csText, csDefault);
  1774.     pWnd->SetFocus();
  1775.     return ptr;
  1776. }
  1777.  
  1778. void CComposeFrame::OnSecurity()
  1779. {
  1780.     m_pComposeBar->UpdateHeaderInfo ( );
  1781.     CGenericFrame::OnSecurity();
  1782. }
  1783.  
  1784. void CComposeFrame::RefreshNewEncoding(int16 doc_csid, BOOL bSave )
  1785. {
  1786.     int16 win_csid = INTL_DocToWinCharSetID(doc_csid);
  1787.     INTL_CharSetInfo c = LO_GetDocumentCharacterSetInfo( GetMainContext()->GetContext() );
  1788.  
  1789.     INTL_SetCSIDocCSID( c, doc_csid );    
  1790.     INTL_SetCSIWinCSID( c, win_csid );
  1791.     
  1792.     SetCSID( doc_csid );
  1793. }
  1794.  
  1795. LRESULT CComposeFrame::OnFindReplace(WPARAM wParam, LPARAM lParam) 
  1796. {
  1797.    if (!m_bUseHtml)
  1798.    {
  1799.       return m_Editor.OnFindReplace(wParam,lParam);
  1800.    }
  1801.    return CGenericFrame::OnFindReplace(wParam,lParam);
  1802. }
  1803.  
  1804. void CComposeFrame::GetMessageString(UINT MenuID, CString& Message) const
  1805. {
  1806. #ifdef EDITOR
  1807.     // static function for both CEditFrame and CComposeFrame
  1808.     //  to get runtime-determined statusline strings for menus
  1809.     if( edt_GetMessageString(GetActiveView(), MenuID, Message) )
  1810.         return;
  1811. #endif
  1812.  
  1813.     CGenericFrame::GetMessageString(MenuID, Message);
  1814. }
  1815.  
  1816. // OnSetMessageString - Override of CGenericFrame's WM_SETMESSAGESTRING message handler. We need this 
  1817. // because the base class is supressing the dynamically-created menu help strings for Composer
  1818. LRESULT CComposeFrame::OnSetMessageString(WPARAM wParam, LPARAM lParam)
  1819. {
  1820.     if( edt_IsEditorDynamicMenu(wParam) )
  1821.         return CFrameWnd::OnSetMessageString(wParam, lParam);
  1822.     else
  1823.         return CGenericFrame::OnSetMessageString(wParam, lParam);
  1824. }
  1825.  
  1826. // rhp - Added for sending the message when the window is not shown
  1827. // This is to wait until attachments are loaded for MAPI Operations
  1828. void CComposeFrame::UpdateComposeWindowForMAPI(void) 
  1829.     if (GetMAPISendMode() == MAPI_SEND)
  1830.     {
  1831.       PostMessage(WM_COMMAND, IDM_SEND); 
  1832.       SetMAPISendMode(MAPI_IGNORE);
  1833.     }
  1834.     else if (GetMAPISendMode() == MAPI_SAVE)
  1835.     {
  1836.       PostMessage(WM_COMMAND, IDM_SAVEASDRAFT); 
  1837.       SetMAPISendMode(MAPI_IGNORE);
  1838.     }
  1839.