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

  1. /* -*- Mode: C++; tab-width: 8; 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.    ComposeFrame.cpp -- Compose window stuff
  20.    Created: Dora Hsu <dora@netscape.com>, 23-Sept-96.
  21.  */
  22.  
  23.  
  24.  
  25. #include "ComposeFrame.h"
  26. #include "EditorFrame.h"
  27. #include "LdapSearchFrame.h"
  28. #include "ComposeFolderView.h"
  29. #include "AddressFolderView.h"
  30. #include "ComposeView.h"
  31. #include "TextEditorView.h"
  32. #include "Command.h"
  33. #include "xpassert.h"
  34. #include "ViewGlue.h"
  35. #include "Dashboard.h"
  36. #include "Xfe/Xfe.h"
  37. #include "edt.h"
  38. #include "../../../lib/libmsg/msgcflds.h"
  39. #include "msgcom.h"
  40. #include <xpgetstr.h>     /* for XP_GetString() */
  41.  
  42. extern "C" int FE_GetMessageBody (MSG_Pane* comppane,
  43.                    char **body,
  44.                    uint32 *body_size,
  45.                    MSG_FontCode **font_changes);
  46.  
  47. extern int XFE_MNC_CLOSE_WARNING;
  48.  
  49. #ifdef DEBUG_dora
  50. #define XDEBUG(x) x
  51. #else
  52. #define XDEBUG(x)
  53. #endif
  54.  
  55. extern "C" {
  56.   void xfe2_EditorInit(MWContext* context);
  57.   void fe_sec_logo_cb (Widget widget, XtPointer closure, XtPointer call_data);
  58.   int fe_YesNoCancelDialog(MWContext* context, char* name, char* message);
  59.   void fe_set_scrolled_default_size(MWContext *context);
  60. }
  61.  
  62. MenuSpec XFE_ComposeFrame::message_attach_menu_spec[] = {
  63.   { xfeCmdAttachFile,            PUSHBUTTON },
  64.   { xfeCmdAttachWebPage,        PUSHBUTTON },
  65.   { xfeCmdDeleteAttachment,        PUSHBUTTON },
  66.   MENU_SEPARATOR,
  67.   { xfeCmdAttachAddressBookCard,    TOGGLEBUTTON },
  68.   { NULL }
  69. };
  70.  
  71. MenuSpec XFE_ComposeFrame::file_menu_spec[] = {
  72.   { "newSubmenu",        CASCADEBUTTON,
  73.     (MenuSpec*)&XFE_Frame::new_menu_spec },
  74.   MENU_SEPARATOR,
  75.   { xfeCmdSaveDraft,        PUSHBUTTON },
  76.   { xfeCmdSaveAs,        PUSHBUTTON },
  77.   MENU_SEPARATOR,
  78.   { xfeCmdSendMessageNow,        PUSHBUTTON },
  79.   { xfeCmdSendMessageLater,        PUSHBUTTON },
  80.   { xfeCmdQuoteOriginalText,    PUSHBUTTON},
  81.   { xfeCmdAddresseePicker,    PUSHBUTTON},
  82.   { xfeCmdAttach,        CASCADEBUTTON,
  83.     (MenuSpec*)&XFE_ComposeFrame::message_attach_menu_spec},
  84.   MENU_SEPARATOR,
  85.   //{ xfeCmdPrintSetup,        PUSHBUTTON },
  86.   //{ xfeCmdPrintPreview,        PUSHBUTTON },
  87.   //{ xfeCmdPrint,        PUSHBUTTON },
  88.   MENU_SEPARATOR,
  89.   { xfeCmdClose,        PUSHBUTTON },
  90.   { xfeCmdExit,        PUSHBUTTON },
  91.   { NULL }
  92. };
  93.  
  94. MenuSpec XFE_ComposeFrame::edit_menu_spec[] = {
  95.   { xfeCmdUndo,            PUSHBUTTON },
  96.   { xfeCmdRedo,            PUSHBUTTON },
  97.   MENU_SEPARATOR,
  98.   { xfeCmdCut,            PUSHBUTTON },
  99.   { xfeCmdCopy,            PUSHBUTTON },
  100.   { xfeCmdPaste,        PUSHBUTTON },
  101.   { xfeCmdPasteAsQuoted,    PUSHBUTTON },
  102.   { xfeCmdDeleteItem,        PUSHBUTTON },
  103.   MENU_SEPARATOR,
  104.   { xfeCmdSelectAll,        PUSHBUTTON },
  105.   MENU_SEPARATOR,
  106.   { xfeCmdFindInObject,        PUSHBUTTON },
  107.   { xfeCmdFindAgain,        PUSHBUTTON },
  108.   { xfeCmdSearchAddress,    PUSHBUTTON },
  109.   MENU_SEPARATOR,
  110.   { xfeCmdEditPreferences,    PUSHBUTTON },
  111.   { NULL }
  112. };
  113.  
  114. static char view_radio_group_name[] = "viewRadiogroup";
  115.  
  116. #define RADIOBUTTON TOGGLEBUTTON, NULL, view_radio_group_name
  117.  
  118. MenuSpec XFE_ComposeFrame::view_menu_spec[] = {
  119.   { xfeCmdToggleNavigationToolbar, PUSHBUTTON },
  120.   { xfeCmdToggleAddressArea, PUSHBUTTON },
  121.   MENU_SEPARATOR,
  122.   { xfeCmdViewAddresses,    RADIOBUTTON },
  123.   { xfeCmdViewAttachments,    RADIOBUTTON },
  124.   { xfeCmdViewOptions,        RADIOBUTTON },
  125.   MENU_SEPARATOR,
  126.   { xfeCmdWrapLongLines,    TOGGLEBUTTON},
  127.   { NULL }
  128. };
  129.  
  130. static MenuSpec text_tools_menu_spec[] = {
  131.     { xfeCmdSpellCheck,    PUSHBUTTON },
  132.     { NULL }
  133. };
  134.  
  135. MenuSpec XFE_ComposeFrame::menu_bar_spec[] = {
  136.   { xfeMenuFile,     CASCADEBUTTON, (MenuSpec*)&XFE_ComposeFrame::file_menu_spec },
  137.   { xfeMenuEdit,     CASCADEBUTTON, (MenuSpec*)&XFE_ComposeFrame::edit_menu_spec },
  138.   { xfeMenuView,     CASCADEBUTTON, (MenuSpec*)&XFE_ComposeFrame::view_menu_spec },
  139.   { xfeMenuTools,     CASCADEBUTTON, (MenuSpec*)&text_tools_menu_spec },
  140.   { xfeMenuWindow,     CASCADEBUTTON, (MenuSpec*)&XFE_Frame::window_menu_spec },
  141.   { xfeMenuHelp,        CASCADEBUTTON, (MenuSpec*)&XFE_Frame::help_menu_spec},
  142.   { NULL }
  143. };
  144.  
  145. ToolbarSpec XFE_ComposeFrame::toolbar_spec[] = {
  146.   { xfeCmdSendMessageNow,    PUSHBUTTON, &MNC_Send_group },
  147.   { xfeCmdQuote,        PUSHBUTTON, &MNC_Quote_group },
  148.   { xfeCmdAddresseePicker,        PUSHBUTTON, &MNC_Address_group },
  149.   {
  150.       xfeCmdAttach,
  151.       CASCADEBUTTON, 
  152.       &MNTB_Next_group, NULL, NULL, NULL,                    // Icons
  153.       message_attach_menu_spec,                                // Submenu spec
  154.       NULL, NULL,                                            // Generate proc/arg
  155.       XFE_TOOLBAR_DELAY_SHORT                                // Popup delay
  156.   },
  157.   { xfeCmdSpellCheck,        PUSHBUTTON, &MNC_SpellCheck_group },
  158.   { xfeCmdSaveDraft,        PUSHBUTTON, &MNC_Save_group },
  159.   TOOLBAR_SEPARATOR,
  160.   { xfeCmdViewSecurity,        PUSHBUTTON, 
  161.             &TB_Unsecure_group,
  162.             &TB_Secure_group,
  163.             &MNTB_SignUnsecure_group,
  164.             &MNTB_SignSecure_group},
  165.   { xfeCmdStopLoading,        PUSHBUTTON, &TB_Stop_group },
  166.   { NULL }
  167. };
  168.  
  169. MenuSpec XFE_ComposeFrame::html_edit_menu_spec[] = {
  170.   { xfeCmdUndo,            PUSHBUTTON },
  171.   { xfeCmdRedo,            PUSHBUTTON },
  172.   MENU_SEPARATOR,
  173.   { xfeCmdCut,            PUSHBUTTON },
  174.   { xfeCmdCopy,            PUSHBUTTON },
  175.   { xfeCmdPaste,        PUSHBUTTON },
  176.   { xfeCmdPasteAsQuoted,    PUSHBUTTON },
  177.   { xfeCmdDeleteItem,        PUSHBUTTON },
  178.   MENU_SEPARATOR,
  179.   { "deleteTableMenu",    CASCADEBUTTON,
  180.     (MenuSpec*)&XFE_EditorFrame::delete_table_menu_spec },
  181.   { xfeCmdRemoveLink,    PUSHBUTTON },
  182.   MENU_SEPARATOR,
  183.   { xfeCmdSelectAll,    PUSHBUTTON },
  184.   { xfeCmdSelectTable,    PUSHBUTTON },
  185.   MENU_SEPARATOR,
  186.   { xfeCmdFindInObject,    PUSHBUTTON },
  187.   { xfeCmdFindAgain,    PUSHBUTTON },
  188.   { xfeCmdSearchAddress,    PUSHBUTTON },
  189.   MENU_SEPARATOR,
  190.   { xfeCmdEditPreferences,PUSHBUTTON },
  191.   { NULL }
  192. };
  193.  
  194. MenuSpec XFE_ComposeFrame::html_view_menu_spec[] = {
  195.   { xfeCmdToggleNavigationToolbar, PUSHBUTTON },
  196.   { xfeCmdToggleAddressArea, PUSHBUTTON },
  197.   { xfeCmdToggleFormatToolbar, PUSHBUTTON },
  198.   MENU_SEPARATOR,
  199.   { xfeCmdViewAddresses,    RADIOBUTTON },
  200.   { xfeCmdViewAttachments,    RADIOBUTTON },
  201.   { xfeCmdViewOptions,        RADIOBUTTON },
  202.   MENU_SEPARATOR,
  203.   { xfeCmdToggleParagraphMarks, PUSHBUTTON }, /* with toggling label */
  204.   MENU_SEPARATOR,
  205.   { xfeCmdViewPageSource,    PUSHBUTTON },
  206.   { xfeCmdViewPageInfo,        PUSHBUTTON },
  207.   MENU_SEPARATOR,
  208.   { "encodingSubmenu",        CASCADEBUTTON,
  209.     (MenuSpec*)&XFE_Frame::encoding_menu_spec },
  210.   { NULL }
  211. };
  212.  
  213. MenuSpec XFE_ComposeFrame::html_menu_bar_spec[] = {
  214.   { xfeMenuFile, CASCADEBUTTON,
  215.     (MenuSpec*)&XFE_ComposeFrame::file_menu_spec },
  216.   { xfeMenuEdit,     CASCADEBUTTON, (MenuSpec*)&html_edit_menu_spec },
  217.   { xfeMenuView,     CASCADEBUTTON, (MenuSpec*)&html_view_menu_spec },
  218.   { xfeMenuInsert,  CASCADEBUTTON,
  219.     (MenuSpec*)&XFE_EditorFrame::insert_menu_spec },
  220.   { xfeMenuFormat,  CASCADEBUTTON,
  221.     (MenuSpec*)&XFE_EditorFrame::format_menu_spec },
  222.   { xfeMenuTools,     CASCADEBUTTON,
  223.     (MenuSpec*)&XFE_EditorFrame::tools_menu_spec },
  224.   { xfeMenuWindow,     CASCADEBUTTON, (MenuSpec*)&XFE_Frame::window_menu_spec },
  225.   { xfeMenuHelp,     CASCADEBUTTON, (MenuSpec*)&XFE_Frame::help_menu_spec },
  226.   { NULL }
  227. };
  228.  
  229. static unsigned html_menu_bar_initialized = 0;
  230.  
  231. XFE_ComposeFrame::XFE_ComposeFrame(Widget toplevel, 
  232.         Chrome *chromespec,
  233.     MWContext *old_context, MSG_CompositionFields *fields,
  234.     const char *draftInitialText, XP_Bool preferToUseHtml)  
  235.     :XFE_Frame("Composition", 
  236.                toplevel,
  237.                old_context ? ViewGlue_getFrame(old_context) : 0,
  238.                FRAME_MAILNEWS_COMPOSE, chromespec, True, True, True, True, True),
  239.     m_destroyWhenConnectionsComplete(False)
  240. {
  241. XDEBUG(    printf ("in XFE_ComposeFrame::XFE_ComposeFrame()\n");)
  242.   geometryPrefName = "mail.compose";
  243.  
  244.   // create the compose view
  245.   XFE_ComposeView *view = new XFE_ComposeView(this, 
  246.         getViewParent(), NULL, m_context, 
  247.         old_context, fields, NULL,
  248.         draftInitialText, preferToUseHtml);
  249.   setView(view);
  250.   
  251.  
  252.   XtVaSetValues(view->getBaseWidget(),
  253.                 XmNleftAttachment,  XmATTACH_FORM,
  254.                 XmNtopAttachment,   XmATTACH_FORM,
  255.                 XmNrightAttachment, XmATTACH_FORM,
  256.                 XmNbottomAttachment, XmATTACH_FORM,
  257.                 NULL);
  258.  
  259.   view->show();
  260.  
  261.   if (preferToUseHtml) {
  262.       if (!html_menu_bar_initialized) {
  263.           fe_EditorInstanciateMenu(this, html_menu_bar_spec);
  264.           html_menu_bar_initialized++;
  265.       }
  266.  
  267.       fe_set_scrolled_default_size(m_context);
  268.  
  269.       setMenubar(html_menu_bar_spec);
  270.   } else {
  271.       setMenubar(menu_bar_spec);
  272.   }
  273.  
  274.   setToolbar(toolbar_spec);
  275.   
  276.  
  277.   // Configure the dashboard
  278.   XP_ASSERT( m_dashboard != NULL );
  279.  
  280.   m_dashboard->setShowSecurityIcon(True);
  281.   m_dashboard->setShowSignedIcon(True);
  282.   m_dashboard->setShowStatusBar(True);
  283.   m_dashboard->setShowProgressBar(True);
  284.  
  285.   if (old_context && CONTEXT_DATA(old_context)->stealth_cmd) {
  286. #ifdef DEBUG_rhess
  287.       fprintf(stderr, "WARNING... [ stealth_cmd ]\n");
  288. #endif
  289.       CONTEXT_DATA(old_context)->stealth_cmd = False;
  290.       CONTEXT_DATA(m_context)->stealth_cmd = False;
  291.   }
  292.  
  293.   // Configure the toolbox for the first time
  294.   configureToolbox();
  295.  
  296.  
  297. XDEBUG(    printf ("leaving XFE_ComposeFrame::XFE_ComposeFrame()\n");)
  298. }
  299.  
  300.  
  301. XFE_ComposeFrame::~XFE_ComposeFrame()
  302. {
  303. XDEBUG(    printf ("in XFE_ComposeFrame::~XFE_ComposeFrame()\n");)
  304.     if (!m_destroyWhenConnectionsComplete)
  305.         ((XFE_ComposeView*)m_view)->destroyPane();
  306.  
  307.     XDEBUG(    printf ("leaving XFE_ComposeFrame::~XFE_ComposeFrame()\n");)
  308. }
  309.  
  310. void
  311. XFE_ComposeFrame::allConnectionsComplete()
  312. {
  313.   MSG_Pane *pane = getPane();
  314.  
  315.   if (!pane) return; // when pane is NULL, don't do anything anymore
  316.  
  317.   // BAD here... Backend will delete the pane inside 
  318.   // MSG_MailCompositionAllConnectionsComplete
  319.  
  320.   MSG_MailCompositionAllConnectionsComplete(pane); 
  321.  
  322.   if (m_destroyWhenConnectionsComplete)
  323.     {
  324.         XDEBUG( printf ("All connections are complete.  Bye bye\n");)
  325.  
  326.         // So, when backend delete the pane, we should set
  327.         // our pane to NULL too so that we will not be
  328.         // checking on an invalid pane
  329.         XDEBUG( printf("XFE_ComposeFrame::allConnectionsComplete()\n");)
  330.  
  331.         if (m_view)
  332.             ((XFE_ComposeView*)m_view)->setPane(NULL);
  333.         delete_response();
  334.     }
  335.   else
  336.     {
  337.         XDEBUG( printf ("All connections are complete.  Notifying interested parties\n");)
  338.         notifyInterested(XFE_Frame::allConnectionsCompleteCallback);
  339.     }
  340. }
  341.  
  342. void
  343. XFE_ComposeFrame::destroyWhenAllConnectionsComplete()
  344. {
  345.     XDEBUG (printf ("****I'm going to destroy myself when all connections are complete\n");)
  346.     m_destroyWhenConnectionsComplete = True;
  347.     XDEBUG (printf("XFE_ComposeFrame::destroyWhenAllConnectionsComplete()\n");)
  348.     if (m_view)
  349.         ((XFE_ComposeView*)m_view)->setPane(NULL);
  350.     if (m_view && ((XFE_ComposeView *)m_view)->isDelayedSent() )
  351.         {
  352.             XDEBUG( printf ("All connections are complete.  Bye bye\n"); )
  353.  
  354.             delete_response();
  355.         }
  356. }
  357.  
  358. MSG_Pane*
  359. XFE_ComposeFrame::getPane()
  360. {
  361.   return (m_view ? ((XFE_ComposeView *)m_view)->getPane(): 0);
  362. }
  363.  
  364.  
  365. XP_Bool
  366. XFE_ComposeFrame::isCommandEnabled(CommandType cmd, void *cd, XFE_CommandInfo* info)
  367. {
  368.   if ( cmd == xfeCmdViewSecurity
  369.        || (cmd == xfeCmdSearchAddress) 
  370.        || cmd == xfeCmdAddresseePicker )
  371.     return True;
  372.   else {
  373.       // NOTE... [ we need to intercept these commands in order to be
  374.       //         [ able to do the "right thing" in the ComposeView
  375.       //
  376.       if ( cmd == xfeCmdCut   ||
  377.            cmd == xfeCmdCopy  ||
  378.            cmd == xfeCmdPaste ||
  379.            cmd == xfeCmdDeleteItem ||
  380.            cmd == xfeCmdUndo
  381.            ) {
  382.           return m_view->isCommandEnabled(cmd, cd, info);
  383.       }
  384.       else 
  385.           return XFE_Frame::isCommandEnabled(cmd, cd, info);
  386.   }
  387. }
  388.  
  389. void
  390. XFE_ComposeFrame::doCommand(CommandType cmd, void *cd, XFE_CommandInfo* info)
  391. {
  392.     if (cmd == xfeCmdSearchAddress)
  393.     {
  394.         fe_showLdapSearch(XfeAncestorFindApplicationShell(getBaseWidget()), this,
  395.                           (Chrome*)NULL);
  396.     }
  397.     // NOTE... [ we need to intercept these commands in order to be
  398.     //         [ able to do the "right thing" in the ComposeView
  399.     //
  400.     else {
  401.         if ( cmd == xfeCmdPaste ||
  402.              cmd == xfeCmdCut   ||
  403.              cmd == xfeCmdCopy  ||
  404.              cmd == xfeCmdDeleteItem ||
  405.              cmd == xfeCmdUndo
  406.              ) {
  407.             m_view->doCommand(cmd, cd, info);
  408.         }
  409.         else
  410.             XFE_Frame::doCommand(cmd, cd, info);
  411.     }
  412. }
  413.  
  414. XP_Bool
  415. XFE_ComposeFrame::handlesCommand(CommandType cmd, void *, XFE_CommandInfo*)
  416. {
  417.   if ( cmd == xfeCmdViewSecurity    ||
  418.        cmd == xfeCmdSearchAddress   ||
  419.        cmd == xfeCmdAddresseePicker ||
  420.        cmd == xfeCmdCut             ||
  421.        cmd == xfeCmdCopy            ||
  422.        cmd == xfeCmdPaste           ||
  423.        cmd == xfeCmdDeleteItem      ||
  424.        cmd == xfeCmdUndo
  425.        )
  426.   {
  427.     return True;
  428.   }
  429.   else
  430.       return XFE_Frame::handlesCommand(cmd);
  431. }
  432.  
  433. XFE_Command*
  434. XFE_ComposeFrame::getCommand(CommandType cmd)
  435. {
  436.     if (m_view)
  437.         return m_view->getCommand(cmd);
  438.     else
  439.         return XFE_Frame::getCommand(cmd);
  440. }
  441.  
  442. int
  443. XFE_ComposeFrame::initEditor()
  444. {
  445.   XFE_ComposeView *c_view = (XFE_ComposeView*)m_view;
  446.  
  447.   return c_view->initEditor();
  448. }
  449.  
  450. extern "C" MSG_Pane *
  451. fe_showCompose(Widget toplevel, Chrome *chromespec, MWContext *old_context, 
  452.            MSG_CompositionFields* fields,
  453.            const char * draftInitialText,
  454.            MSG_EditorType editorType,
  455.                XP_Bool defaultAddressIsNewsgroup)
  456. {
  457.     // not a static global, since we can have multiple editors.
  458.     XFE_ComposeFrame *theFrame = NULL;
  459.   
  460.     XDEBUG(    printf ("in fe_showCompose()\n");)
  461.  
  462.     XP_Bool useHtml;
  463.  
  464.     if (editorType == MSG_HTML_EDITOR) {
  465.         useHtml = TRUE;
  466.     }
  467.     else {
  468.         if (editorType == MSG_PLAINTEXT_EDITOR) {
  469.             useHtml = FALSE;
  470.         }
  471.         else {
  472.             if (old_context && CONTEXT_DATA(old_context)->stealth_cmd) {
  473.                 useHtml = !fe_globalPrefs.send_html_msg;
  474.             }
  475.             else {
  476.                 useHtml = fe_globalPrefs.send_html_msg;
  477.             }
  478.         }
  479.     }
  480.     
  481.     if (old_context)
  482.         CONTEXT_DATA(old_context)->stealth_cmd = False;
  483.  
  484.     if (!fields)
  485.         fields = new MSG_CompositionFields();
  486.  
  487.     theFrame = new XFE_ComposeFrame(toplevel, chromespec, old_context, fields, 
  488.                                     draftInitialText, useHtml);
  489.         if (defaultAddressIsNewsgroup) {
  490.             // dig deep to determine if this window has any recipients.
  491.             // If not, and the caller asked to default address type to
  492.             // "Newsgroup:", then dig down again and change address header.
  493.             // for the first item in the empty address list.
  494.             // (only known user of this flag is XFE_TaskBarDrop::openComposeWindow())
  495.             XFE_ComposeView *cv=(XFE_ComposeView*)(theFrame->getView());
  496.             XFE_ComposeFolderView *cfv=(XFE_ComposeFolderView*)cv->getComposeFolderView();
  497.             XFE_AddressFolderView *afv=cfv->getAddrFolderView();
  498.  
  499.             if (afv->getTotalData()==0)
  500.                   afv->setHeader(0, MSG_NEWSGROUPS_HEADER_MASK);
  501.         }
  502.  
  503.     theFrame->show();
  504.     
  505.     if (useHtml) {
  506.         MWContext *context = theFrame->getContext();
  507.         fe_UserActivity(context);
  508.         xfe2_EditorInit(context); // im registration, focus event handlers, ...
  509.         theFrame->initEditor();
  510.     }
  511.  
  512.     XDEBUG(    printf ("leaving fe_showCompose()\n");)
  513.  
  514.     return ((XFE_ComposeFrame*)theFrame)->getPane();
  515. }
  516.  
  517. int
  518. XFE_ComposeFrame::getSecurityStatus()
  519. {
  520.     XP_Bool is_signed = False; 
  521.     XP_Bool is_encrypted = False;
  522.     XFE_MailSecurityStatusType status = XFE_UNSECURE_UNSIGNED;
  523.  
  524.     XDEBUG(printf("XFE_ComposeFrame::getSecurityStatus\n");)
  525.  
  526.     if (getPane() == NULL) return XFE_UNSECURE_UNSIGNED;
  527.  
  528.     // Encrypted
  529.     if ( MSG_GetCompBoolHeader(getPane(), MSG_ENCRYPTED_BOOL_HEADER_MASK) )
  530.     {
  531.         is_encrypted = True;
  532.     }
  533.  
  534.     // Signed
  535.     if ( MSG_GetCompBoolHeader(getPane(), MSG_SIGNED_BOOL_HEADER_MASK) )
  536.     {
  537.         is_signed = True;
  538.     }
  539.  
  540.     if (is_encrypted && is_signed ) 
  541.     {
  542.         status = XFE_SECURE_SIGNED;
  543.     }
  544.     else if (!is_encrypted && is_signed) 
  545.     {
  546.           status = XFE_UNSECURE_SIGNED;
  547.     }
  548.     else if (is_encrypted && !is_signed) 
  549.     {
  550.           status = XFE_SECURE_UNSIGNED;
  551.     }
  552.     else if (!is_encrypted && !is_signed )
  553.     {
  554.            status = XFE_UNSECURE_UNSIGNED;
  555.     }
  556.    return status;
  557. }
  558.  
  559. XP_Bool
  560. XFE_ComposeFrame::isOkToClose()
  561. {
  562.   char *pBody;
  563.   uint32 bodySize;
  564.   MSG_FontCode *font_changes;
  565.  
  566.   MWContext* context = getContext();
  567.   XP_Bool okToClose;
  568.  
  569.   if ( m_destroyWhenConnectionsComplete) 
  570.   {
  571.     return True;
  572.   }
  573.  
  574.   XFE_ComposeView *c_view = (XFE_ComposeView*)m_view;
  575.   int  n = 0;
  576.  
  577.   if (c_view->isHTML()) {
  578.       // NOTE:  we need to "shutdown" edt plugins before
  579.       //        doing anything else...
  580.       //
  581.       n = 0;
  582.       while (EDT_IsPluginActive(context)) {
  583.           EDT_StopPlugin(context);
  584. #ifdef DEBUG_rhess
  585.           fprintf(stderr, "stop::[ %d ]\n", n);
  586. #endif
  587.           fe_EventLoop ();
  588.           n++;
  589.       }
  590.  
  591.       n = 0;
  592.       while (EDT_IsBlocked(context)) {
  593. #ifdef DEBUG_rhess
  594.           fprintf(stderr, "pause::[ %d ]\n", n);
  595. #endif
  596.           fe_EventLoop ();
  597.           n++;
  598.       }
  599.   }
  600.  
  601.   // If there is no message body and there are no attachments,
  602.   // don't offer to save as a draft:
  603.   FE_GetMessageBody(getPane(), &pBody, &bodySize, &font_changes);
  604.   XP_FREE(pBody);
  605.   if (bodySize == 0)
  606.   {
  607.       // getAttachmentData() doesn't always tell us about attachments!
  608.       if ((c_view == 0) || (c_view->getAttachmentData() == 0))
  609.       return True;
  610.   }
  611.  
  612.   if ( !((XFE_ComposeView*)m_view)->isModified() ) return True;
  613.  
  614.   int state = fe_YesNoCancelDialog(context, "composeCloseWarning", 
  615.         XP_GetString(XFE_MNC_CLOSE_WARNING));
  616.  
  617.   if (state == XmDIALOG_OK_BUTTON) 
  618.   {
  619.         n = 0;
  620.  
  621.         c_view->doCommand( xfeCmdSaveDraft, NULL,NULL);
  622.  
  623.         if (c_view->isHTML()) {
  624.             XtUnmapWidget(getChromeParent());
  625.  
  626.             XSync(XtDisplay(getChromeParent()), False);
  627.  
  628.             // NOTE:  we need to let edt plugins "cleanup" after
  629.             //        the SaveDraft before waiting on the editor 
  630.             //        to finish it's work...
  631.             //
  632.             n = 0;
  633.             while (EDT_IsPluginActive(context)) {
  634. #ifdef DEBUG_rhess
  635.                 fprintf(stderr, "plug::[ %d ]\n", n);
  636. #endif
  637.                 fe_EventLoop ();
  638.                 n++;
  639.             }
  640.  
  641.             n = 0;
  642.             while (EDT_IsBlocked(context)) {
  643. #ifdef DEBUG_rhess
  644.                 fprintf(stderr, "wait::[ %d ]\n", n);
  645. #endif
  646.                 fe_EventLoop ();
  647.                 n++;
  648.             }
  649.         }
  650.         okToClose = True;
  651.   }
  652.   else if (state == XmDIALOG_APPLY_BUTTON )
  653.   {
  654.     okToClose = True;
  655.   } 
  656.   else 
  657.   { 
  658.     okToClose = False;
  659.   }
  660.   return okToClose;
  661. }
  662.  
  663. //////////////////////////////////////////////////////////////////////////
  664. //
  665. // Toolbox methods
  666. //
  667. //////////////////////////////////////////////////////////////////////////
  668. void
  669. XFE_ComposeFrame::toolboxItemClose(XFE_ToolboxItem * item)
  670. {
  671.     XP_ASSERT( item != NULL );
  672.  
  673.     // Message_Toolbar
  674.     if (item == m_toolbar)
  675.     {
  676.         fe_globalPrefs.compose_message_message_toolbar_open = False;
  677.     }
  678. }
  679. //////////////////////////////////////////////////////////////////////////
  680. void
  681. XFE_ComposeFrame::toolboxItemOpen(XFE_ToolboxItem * item)
  682. {
  683.     XP_ASSERT( item != NULL );
  684.  
  685.     // Message_Toolbar
  686.     if (item == m_toolbar)
  687.     {
  688.         fe_globalPrefs.compose_message_message_toolbar_open = True;
  689.     }
  690. }
  691. //////////////////////////////////////////////////////////////////////////
  692. void
  693. XFE_ComposeFrame::toolboxItemChangeShowing(XFE_ToolboxItem * item)
  694. {
  695.     XP_ASSERT( item != NULL );
  696.  
  697.     // Message_Toolbar
  698.     if (item == m_toolbar)
  699.     {
  700.         fe_globalPrefs.compose_message_message_toolbar_showing = item->isShown();
  701.     }
  702. }
  703. //////////////////////////////////////////////////////////////////////////
  704. void
  705. XFE_ComposeFrame::configureToolbox()
  706. {
  707.     // If a the frame was constructed with a chromespec, then we ignore
  708.     // all the preference magic.
  709.     if (m_chromespec_provided)
  710.     {
  711.         return;
  712.     }
  713.  
  714.     // Make sure the toolbox is alive
  715.     if (!m_toolbox || (m_toolbox && !m_toolbox->isAlive()))
  716.     {
  717.         return;
  718.     }
  719.  
  720.     // Message_Toolbar
  721.     if (m_toolbar)
  722.     {
  723.         m_toolbar->setShowing(fe_globalPrefs.compose_message_message_toolbar_showing);
  724.         m_toolbar->setOpen(fe_globalPrefs.compose_message_message_toolbar_open);
  725.     }
  726. }
  727. //////////////////////////////////////////////////////////////////////////
  728.