home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / xfe / src / ComposeView.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  66.2 KB  |  2,545 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.    ComposeView.cpp -- presents view for composing a mail messages.
  20.    Created: Dora Hsu <dora@netscape.com>, 23-Sept-96.
  21.    */
  22.  
  23.  
  24.  
  25. #include "xfe2_extern.h"
  26. #include "ComposeView.h"
  27. #include "ComposeFolderView.h"
  28. #include "AddressOutliner.h"
  29. #include "TextEditorView.h"
  30. #include "EditorView.h"
  31. #include "Command.h"
  32. #include "new_manage.h"
  33. #include "xp_mem.h"
  34. #include "ViewGlue.h"
  35. #include <Xm/Frame.h>
  36. #include <Xfe/ToolBox.h>
  37. #include "xfe.h"
  38. #include "edt.h"
  39. #include "felocale.h"
  40. #include "intl_csi.h"
  41. #include "secnav.h"
  42.  
  43. #include "xeditor.h"
  44.  
  45. /* for XP_GetString() */
  46. #include <xpgetstr.h>
  47. extern int MK_MSG_EMPTY_MESSAGE;
  48. extern int MK_MSG_DOUBLE_INCLUDE;
  49. extern int MK_MSG_MIXED_SECURITY;
  50. extern int MK_MSG_MISSING_SUBJECT;
  51. extern int XFE_NO_SUBJECT;
  52.  
  53. #include "prefs.h"
  54.  
  55. #if defined(DEBUG_dora) || defined(DEBUG_sgidev)
  56. #define XDEBUG(x) x
  57. #else
  58. #define XDEBUG(x)
  59. #endif
  60.  
  61. static Atom XFE_TEXT_ATOM = 0;
  62.  
  63. extern "C" {
  64.   void           xfe2_EditorInit(MWContext* context);
  65.   void           xfe2_EditorImSetCoords(MWContext* context);
  66.   void           xfe2_EditorCaretHide(MWContext* context);
  67.   void           xfe2_EditorCaretShow(MWContext* context);
  68.   void           xfe2_EditorWaitWhileContextBusy(MWContext* context);
  69.   char          *xfe2_GetClipboardText(Widget focus, int32 *internal);
  70.   CL_Compositor *fe_create_compositor(MWContext *context);
  71.   Boolean        fe_EditorCanPasteCache(MWContext* context, int32* r_length);
  72.   Boolean        fe_EditorCanPasteLocal(MWContext* context, int32* r_length);
  73.   Boolean        fe_EditorCanPasteText(MWContext* context, int32* r_length);
  74.   Boolean        fe_EditorCut(MWContext* context, Time timestamp);
  75.   Boolean        fe_EditorCopy(MWContext* context, Time timestamp);
  76.   Boolean        fe_EditorPaste(MWContext* context, Time timestamp);
  77.   Widget         fe_EditorCreateComposeToolbar(MWContext*, Widget, char*);
  78. }
  79.  
  80.  
  81. extern "C" XtPointer fe_GetFont(MWContext *context, int sizeNum, int fontmask);
  82. extern "C" void
  83. fe_set_compose_wrap_state(MWContext *context, XP_Bool wrap_p);
  84.  
  85. extern "C" void fe_addToContextList(MWContext *context);
  86.  
  87. extern "C" void fe_cut_cb (Widget widget, XtPointer closure,
  88.                                XtPointer call_data);
  89. extern "C" void fe_paste_cb(Widget widget, XtPointer closure,
  90.                                XtPointer call_data);
  91. extern "C" void fe_copy_cb (Widget widget, XtPointer closure,
  92.                                XtPointer call_data);
  93. extern "C" void fe_paste_quoted_cb (Widget widget, XtPointer closure,
  94.                                XtPointer call_data);
  95. extern "C" void fe_mailNew_cb (Widget widget, XtPointer closure,
  96.                                XtPointer call_data);
  97. extern "C" void fe_load_default_font (MWContext *context);
  98. extern "C" void fe_find_scrollbar_sizes (MWContext *context);
  99. extern "C" void fe_get_final_context_resources (MWContext *context);
  100. extern "C" void fe_InitScrolling (MWContext *context);
  101. extern "C" void fe_InitRemoteServerWindow (MWContext *context);
  102. extern "C" void fe_SensitizeMenus (MWContext *context);
  103. extern "C" int FE_GetMessageBody (MSG_Pane* comppane,
  104.                    char **body,
  105.                    uint32 *body_size,
  106.                    MSG_FontCode **font_changes);
  107. extern XtResource fe_Resources[];
  108. extern Cardinal fe_ResourcesSize;
  109.  
  110. const char *XFE_ComposeView::tabBeforeSubject = "XFE_ComposeView::tabBeforeSubject";
  111. const char *XFE_ComposeView::tabAfterSubject = "XFE_ComposeView::tabAfterSubject";
  112. const char *XFE_ComposeView::tabPrev   = "XFE_ComposeView::tabPrev";
  113. const char *XFE_ComposeView::tabNext   = "XFE_ComposeView::tabNext";
  114. const char *XFE_ComposeView::updateSecurityOption= "XFE_ComposeView::updateSecurityOption";
  115.  
  116. static void TabBeforeSubjectTraverse(Widget w, XEvent *, String *, Cardinal *)
  117. {
  118.    XtPointer client;
  119.    XFE_ComposeView *obj ;
  120.  
  121.    XtVaGetValues( w, XmNuserData, &client, 0);
  122.  
  123.    XDEBUG(printf("Inside ... TabBeforeSubjectTraverse to notify...\n");)
  124.  
  125.    obj = (XFE_ComposeView *) client;
  126.    obj->getToplevel()->notifyInterested(XFE_ComposeView::tabBeforeSubject, client);
  127. }
  128.  
  129. static void TabAfterSubjectTraverse(Widget w, XEvent *, String *, Cardinal *)
  130. {
  131.    XtPointer client;
  132.    XFE_ComposeView *obj ;
  133.  
  134.    XtVaGetValues( w, XmNuserData, &client, 0);
  135.    XDEBUG(printf("Inside ... TabAfterSubjectTraverse to notify...\n");)
  136.  
  137.    obj = (XFE_ComposeView *) client;
  138.    obj->getToplevel()->notifyInterested(XFE_ComposeView::tabAfterSubject, client);
  139. }
  140.  
  141. extern XtAppContext fe_XtAppContext;
  142.  
  143. static XtActionsRec actions[] =
  144.   {{"PrevTabTraverse",     TabBeforeSubjectTraverse     },
  145.    {"NextTabTraverse",     TabAfterSubjectTraverse     }};
  146.  
  147.  
  148. static char prevtraverseTranslations[] =
  149. "~Ctrl Shift <Key>Tab:  PrevTabTraverse()\n\
  150.   Ctrl Shift <Key>Tab:  NextTabTraverse()\n\
  151.       ~Shift <Key>Tab:  NextTabTraverse()";
  152.  
  153.  
  154.  
  155. static void PrevTabTraverse(Widget w, XEvent *, String *, Cardinal *)
  156. {
  157.    XtPointer client;
  158.    XFE_ComposeView *obj ;
  159.  
  160. #ifdef DEBUG_rhess
  161.    fprintf(stderr, "Editor::[ PrevTabTraverse ]\n");
  162. #endif
  163.  
  164.    XtVaGetValues( w, XmNuserData, &client, 0);
  165.  
  166.    obj = (XFE_ComposeView *) client;
  167.    obj->getToplevel()->notifyInterested(XFE_ComposeView::tabPrev, client);
  168. }
  169.  
  170. static void NextTabTraverse(Widget w, XEvent *, String *, Cardinal *)
  171. {
  172.    XtPointer client;
  173.    XFE_ComposeView *obj ;
  174.  
  175. #ifdef DEBUG_rhess
  176.    fprintf(stderr, "Editor::[ NextTabTraverse ]\n");
  177. #endif
  178.  
  179.    XtVaGetValues( w, XmNuserData, &client, 0);
  180.  
  181.    obj = (XFE_ComposeView *) client;
  182.    obj->getToplevel()->notifyInterested(XFE_ComposeView::tabNext, client);
  183. }
  184.  
  185. extern XtAppContext fe_XtAppContext;
  186.  
  187. static XtActionsRec cv_actions[] =
  188. {{"CvTabTraversePrev",    PrevTabTraverse     },
  189.  {"CvTabTraverseNext",    NextTabTraverse     }};
  190.  
  191.  
  192. static char cvTraverseTranslations[] =
  193. "~Meta ~Alt Ctrl ~Shift <Key>Tab:  CvTabTraversePrev()\n\
  194.  ~Meta ~Alt Ctrl  Shift <Key>Tab:  CvTabTraverseNext()";
  195.  
  196.  
  197.  
  198. XFE_ComposeView::XFE_ComposeView(XFE_Component *toplevel_component,
  199.                  Widget parent,
  200.                  XFE_View *parent_view,
  201.                  MWContext *context,
  202.                  MWContext *context_to_copy, 
  203.                  MSG_CompositionFields * fields,
  204.                  MSG_Pane *p,
  205.                  const char *pInitialText,
  206.                  XP_Bool preferToUseHtml)
  207.   : XFE_MNView(toplevel_component, parent_view, context, p)
  208. {
  209.   INTL_CharSetInfo c;
  210.   INTL_CharSetInfo c_to_copy;
  211.      
  212.   c = LO_GetDocumentCharacterSetInfo(context);
  213.   if (context_to_copy)
  214.   c_to_copy = LO_GetDocumentCharacterSetInfo(context_to_copy);
  215.   else
  216.         c_to_copy = c;
  217.  
  218.   MSG_Pane *pane = NULL;
  219.  
  220.   // XXX should really be done in the frame..
  221.   if (context_to_copy)
  222.   CONTEXT_DATA(m_contextData)->xfe_doc_csid = 
  223.         CONTEXT_DATA(context_to_copy)->xfe_doc_csid;
  224.   else
  225.         CONTEXT_DATA(m_contextData)->xfe_doc_csid = fe_globalPrefs.doc_csid;
  226.  
  227.   INTL_SetCSIWinCSID(c, INTL_GetCSIWinCSID(c_to_copy));
  228.  
  229.   mailComposer = NULL;
  230.   mailAttachment = NULL;
  231.   m_expanded = True;
  232.   m_toolbarW = NULL;
  233.   m_format_toolbar = NULL;
  234.   m_editorFormW = NULL;
  235.   m_subjectFormW = NULL;
  236.   m_editorFocusP = False;
  237.   m_subjectW = NULL;
  238.   m_addrTextW = NULL;
  239.   m_addrTypeW = NULL;
  240.   m_focusW = NULL;
  241.   m_nullW  = NULL;
  242.   m_daW    = NULL;
  243.   m_topW   = NULL;
  244.  
  245.   m_folderViewAlias = NULL; // These are just pointer aliases to views
  246.   m_textViewAlias = NULL;   // this class does not own these views
  247.   m_htmlViewAlias = NULL;   // It's the parent class who owns these views
  248.   m_delayedSent = False;
  249.   m_plaintextP = !fe_globalPrefs.send_html_msg;
  250.   m_pInitialText = NULL;
  251.   if ( pInitialText && strlen(pInitialText) )
  252.       m_pInitialText = XP_STRDUP(pInitialText);
  253.  
  254.   m_requestHTML = preferToUseHtml;
  255.   m_initEditorP = False;
  256.   m_postEditorP = False;
  257.   m_puntEditorP = False;
  258.   m_delayEditorP = False;
  259.   m_dontQuoteP = False;
  260.  
  261.   if ( m_requestHTML ) {
  262.       m_plaintextP = False;
  263.   }
  264.   else {
  265.       m_plaintextP = True;
  266.   }
  267.  
  268. #ifdef DEBUG_rhess
  269.     if (m_plaintextP)
  270.         fprintf(stderr, "ComposeView::[ plaintext ]\n");
  271.     else
  272.         fprintf(stderr, "ComposeView::[ HTML ]\n");
  273. #endif
  274.  
  275.   getToplevel()->registerInterest(XFE_Component::afterRealizeCallback,
  276.              this,
  277.              (XFE_FunctionNotification)afterRealizeWidget_cb); 
  278.  
  279.   { // Create base widgets
  280.     Widget w;
  281.     /*w = XmCreateForm(parent, "composeViewBaseWidget", NULL, 0);*/
  282.  
  283.     w = XtVaCreateWidget("panedw",
  284.                 xmPanedWindowWidgetClass,
  285.                         parent,
  286.             XmNnavigationType, XmTAB_GROUP,
  287.                         NULL);
  288.     setBaseWidget(w);
  289.   }
  290.  
  291.  
  292.  
  293.   if (!p)
  294.   {
  295.     pane = MSG_CreateCompositionPane(m_contextData, 
  296.                      //context_to_copy required by xp
  297.                      context_to_copy, 
  298.                      fe_mailNewsPrefs, fields,  XFE_MNView::m_master );
  299.     setPane(pane);
  300.     CONTEXT_DATA(m_contextData)->comppane = (MSG_Pane*)pane;
  301.  
  302.     CONTEXT_DATA(m_contextData)->mcCitedAndUnedited = True;
  303.     CONTEXT_DATA(m_contextData)->mcEdited = False;
  304.   }
  305.  
  306.   CONTEXT_DATA (m_contextData)->compose_wrap_lines_p = True;
  307.  
  308.   createWidget(getBaseWidget());
  309. }
  310.  
  311. XFE_ComposeView::~XFE_ComposeView()
  312. {
  313.     //  destroyPane();    
  314.     // Don't call this here.  Calling MSG_MailCompositionAllConnections- 
  315.     //  complete will destroy the composition pane.
  316.  
  317.     if (!m_plaintextP) {
  318.         XtRemoveEventHandler(m_subjectW, 
  319.                              ButtonPressMask, FALSE, unGrabEditorProc, this);
  320.         XtRemoveEventHandler(m_daW,  
  321.                              FocusChangeMask, FALSE, daFocusProc, this);
  322.         XtRemoveEventHandler(m_topW, 
  323.                              FocusChangeMask, FALSE, topFocusProc, this);
  324.         if (m_nullW)
  325.             XtRemoveEventHandler(m_nullW, FocusChangeMask, FALSE, 
  326.                                  nullFocusProc, this);
  327.     }
  328. }
  329.  
  330. static ToolbarSpec alignment_menu_spec[] = {
  331.     { xfeCmdSetAlignmentStyleLeft,     PUSHBUTTON, &ed_left_group },
  332.     { xfeCmdSetAlignmentStyleCenter, PUSHBUTTON, &ed_center_group },
  333.     { xfeCmdSetAlignmentStyleRight,     PUSHBUTTON, &ed_right_group },
  334.     { NULL }
  335. };
  336.  
  337. static ToolbarSpec goodies_menu_spec[] = {
  338.     { xfeCmdInsertLink,           PUSHBUTTON, &ed_link_group   },
  339.     { xfeCmdInsertTarget,         PUSHBUTTON, &ed_target_group },
  340.     { xfeCmdInsertImage,          PUSHBUTTON, &ed_image_group  },
  341.     { xfeCmdInsertHorizontalLine, PUSHBUTTON, &ed_hrule_group  },
  342.     { xfeCmdInsertTable,          PUSHBUTTON, &ed_table_group  },
  343.     { NULL }
  344. };
  345.  
  346. static ToolbarSpec editor_style_toolbar_spec[] = {
  347.  
  348.     { xfeCmdSetParagraphStyle, COMBOBOX },
  349.     { xfeCmdSetFontFace,       COMBOBOX },
  350.     { xfeCmdSetFontSize,       COMBOBOX },
  351.     { xfeCmdSetFontColor,      COMBOBOX },
  352.     TOOLBAR_SEPARATOR,
  353.  
  354.     { xfeCmdToggleCharacterStyleBold,       TOGGLEBUTTON, &ed_bold_group },
  355.     { xfeCmdToggleCharacterStyleItalic,       TOGGLEBUTTON, &ed_italic_group },
  356.     { xfeCmdToggleCharacterStyleUnderline, TOGGLEBUTTON, &ed_underline_group },
  357.     { xfeCmdClearAllStyles,                PUSHBUTTON  , &ed_clear_group },
  358.     TOOLBAR_SEPARATOR,
  359.  
  360.     { xfeCmdInsertBulletedList,    TOGGLEBUTTON, &ed_bullet_group },
  361.     { xfeCmdInsertNumberedList,    TOGGLEBUTTON, &ed_number_group },
  362.     TOOLBAR_SEPARATOR,
  363.  
  364.     { xfeCmdOutdent,    PUSHBUTTON, &ed_outdent_group },
  365.     { xfeCmdIndent,    PUSHBUTTON, &ed_indent_group },
  366.     { xfeCmdSetAlignmentStyle, CASCADEBUTTON, &ed_left_group, 0, 0, 0,
  367.       (MenuSpec*)&alignment_menu_spec },
  368.     { "editorGoodiesMenu", CASCADEBUTTON, &ed_insert_group, 0, 0, 0,
  369.       (MenuSpec*)&goodies_menu_spec },
  370.     { NULL }
  371. };
  372.  
  373. void
  374. XFE_ComposeView::createSubjectBar(Widget parent)
  375. {
  376.    Cardinal ac =0;
  377.    Arg av[20];
  378.    m_subjectFormW = XtVaCreateManagedWidget("subjectFormW",
  379.             xmFormWidgetClass,  parent,
  380.             XmNtopAttachment, XmATTACH_FORM,
  381.             XmNleftAttachment, XmATTACH_FORM,
  382.             XmNrightAttachment, XmATTACH_FORM,
  383.             XmNbottomAttachment, XmATTACH_NONE, 0);
  384.  
  385.    ac = 0;
  386.    XtSetArg (av [ac], XmNtopAttachment, XmATTACH_FORM); ac++;
  387.    if (m_plaintextP) {
  388.     XtSetArg (av [ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
  389.    }
  390.    else {
  391.     XtSetArg (av [ac], XmNtraversalOn, False); ac++;
  392.    }
  393.    XtSetArg (av [ac], XmNleftAttachment, XmATTACH_FORM); ac++;
  394.    XtSetArg (av [ac], XmNrightAttachment, XmATTACH_NONE); ac++;
  395.    XtSetArg (av [ac], XmNarrowDirection, XmARROW_UP); ac++;
  396.    XtSetArg (av [ac], XmNtraversalOn, False); ac++;
  397.    XtSetArg (av [ac], XmNshadowThickness, 0); ac++;
  398.    m_expand_arrowW = XmCreateArrowButton(m_subjectFormW, "toggleAddressArea",
  399.                                          av, ac);
  400.    fe_WidgetAddToolTips(m_expand_arrowW);
  401.  
  402.    m_expanded = True;
  403.    XtAddCallback(m_expand_arrowW, XmNactivateCallback, expandCallback, this);
  404.    XtManageChild(m_expand_arrowW);
  405.  
  406.  
  407.     /* Create the text field */
  408.     char  name[30];
  409.     char  buf[100];
  410.     Widget subjectLabelW;
  411.  
  412.     PR_snprintf(name, sizeof (name), "%s", "subject");
  413.  
  414.     ac = 0;
  415.     XtSetArg(av[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++;
  416.     XtSetArg(av[ac], XmNleftWidget, m_expand_arrowW); ac++;
  417.     XtSetArg(av[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
  418.     if (m_plaintextP) {
  419.     XtSetArg(av[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
  420.     }
  421.     XtSetArg(av[ac], XmNrightAttachment, XmATTACH_NONE); ac++;
  422.     PR_snprintf(buf, sizeof (buf), "%sLabel", name);
  423.     subjectLabelW = XmCreateLabelGadget(m_subjectFormW, buf, av, ac);
  424.     XtManageChild(subjectLabelW);
  425.  
  426.     Dimension height;
  427.  
  428.     ac =0;
  429.     m_subjectW = fe_CreateTextField(m_subjectFormW, name, av, ac);
  430.  
  431.     XtVaGetValues(m_subjectW, XmNheight, &height, 0);
  432.  
  433.     // Set default priority...should be consistent with default menu priority toggle state
  434.     ((XFE_ComposeFolderView*)m_folderViewAlias)->selectPriority(MSG_NormalPriority);
  435.  
  436.     Widget toolbox_widget = NULL;
  437.        
  438.     if (!m_plaintextP) {
  439.         XFE_Component* top_level = getToplevel();
  440.         Widget         top_widget = top_level->getBaseWidget();
  441.  
  442.         //    I don't think we need this anymore...djw
  443.         CONTEXT_DATA(getContext())->top_area = top_widget;
  444.     
  445.         XFE_Toolbox* toolbox = new XFE_Toolbox(top_level, m_subjectFormW);
  446.         
  447.         toolbox_widget = toolbox->getBaseWidget();
  448.  
  449.         // Make sure the toolbox is efficiently resized
  450.         XtVaSetValues(toolbox_widget,XmNusePreferredHeight,True,NULL);
  451.  
  452.         toolbox->show(); // manage
  453.  
  454.         m_format_toolbar = new XFE_EditorToolbar(top_level,
  455.                                                  toolbox,
  456.                                                  "formattingToolbar",
  457.                                      (ToolbarSpec*)&editor_style_toolbar_spec,
  458.                                                  False);
  459.     }
  460.  
  461.     // Register Action
  462.  
  463.     XtAppAddActions( fe_XtAppContext, actions,  2);
  464.  
  465.     XtVaSetValues(m_subjectW, XmNuserData, this,  NULL);
  466.     XtOverrideTranslations(m_subjectW, 
  467.         XtParseTranslationTable(prevtraverseTranslations));
  468.  
  469.  
  470.     if (!m_plaintextP) {
  471.         XtInsertEventHandler(m_subjectW, ButtonPressMask, FALSE, 
  472.                              unGrabEditorProc, this, XtListTail);
  473.     }
  474.  
  475.     ac = 0;
  476.     XtSetArg(av[ac], XmNleftAttachment, XmATTACH_WIDGET); ac++;
  477.     XtSetArg(av[ac], XmNleftWidget, subjectLabelW); ac++;
  478.     XtSetArg(av[ac], XmNtopAttachment, XmATTACH_FORM); ac++;
  479.     if (m_plaintextP) {
  480.     XtSetArg(av[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
  481.     }
  482.     XtSetArg(av[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
  483.     XtSetArg(av[ac], XmNrightOffset, 5); ac++;
  484.     XtSetArg(av[ac], XmNtraversalOn, True); ac++;
  485.     XtSetArg(av[ac], XmNhighlightOnEnter, True); ac++;
  486.     XtSetValues(m_subjectW, av, ac);
  487.     XtManageChild(m_subjectW);
  488.  
  489.     if (!m_plaintextP) {
  490.     ac = 0;
  491.     XtSetArg(av[ac], XmNtopAttachment, XmATTACH_WIDGET); ac++;
  492.     XtSetArg(av[ac], XmNtopWidget, m_subjectW); ac++;
  493.     XtSetArg(av[ac], XmNbottomAttachment, XmATTACH_FORM); ac++;
  494.     XtSetArg(av[ac], XmNleftAttachment, XmATTACH_FORM); ac++;
  495.     XtSetArg(av[ac], XmNrightAttachment, XmATTACH_FORM); ac++;
  496.     XtSetArg(av[ac], XmNtraversalOn, False); ac++;
  497.     XtSetValues(toolbox_widget, av, ac);
  498.     XtManageChild(toolbox_widget);
  499.     }
  500.  
  501.     if (fe_globalData.nonterminal_text_translations) {
  502.       XtOverrideTranslations(m_subjectW,
  503.                        fe_globalData.nonterminal_text_translations);
  504.      }
  505.  
  506.     
  507.     if (m_plaintextP) {
  508.         getToplevel()->registerInterest( XFE_TextEditorView::textFocusIn, 
  509.                      this, (XFE_FunctionNotification)textEditorFocusIn_cb);
  510.     }
  511.     getToplevel()->registerInterest( XFE_AddressOutliner::textFocusIn, this,
  512.                    (XFE_FunctionNotification)addressTextFocusIn_cb);
  513.     getToplevel()->registerInterest( XFE_AddressOutliner::typeFocusIn, this,
  514.                    (XFE_FunctionNotification)addressTypeFocusIn_cb);
  515.  
  516.    getToplevel()->registerInterest( XFE_AddressOutliner::tabNext, this,
  517.                    (XFE_FunctionNotification)tabToSubject_cb);
  518.  
  519.    getToplevel()->registerInterest( XFE_ComposeView::tabPrev, this,
  520.                    (XFE_FunctionNotification)tabToSubject_cb);
  521.  
  522.    setDefaultSubjectHeader();
  523.  
  524.    // Add callback after the default subject has been set to avoid
  525.    // extra trip to valueChangeCallback
  526.    XtAddCallback(m_subjectW, XmNvalueChangedCallback, 
  527.                  subjectChangeCallback, (XtPointer)this);
  528.  
  529.    XtAddCallback(m_subjectW, XmNfocusCallback, 
  530.                  subjectFocusIn_CB, (XtPointer)this);
  531. }
  532.  
  533. void
  534. XFE_ComposeView::setDefaultSubjectHeader()
  535. {
  536.   const char * subject = MSG_GetCompHeader(getPane(),MSG_SUBJECT_HEADER_MASK);
  537.   char *pStr = XP_STRDUP(subject);
  538.  
  539.  
  540.   if (pStr && strlen(pStr))
  541.   {
  542.      fe_SetTextFieldAndCallBack(m_subjectW, pStr);
  543.   }
  544.   XP_FREE(pStr);
  545. }
  546.  
  547. void
  548. XFE_ComposeView::show()
  549. {
  550.     if (!m_plaintextP && m_format_toolbar != NULL)
  551.         m_format_toolbar->show();
  552.  
  553.     XFE_MNView::show(); // call super
  554. }
  555.  
  556. void
  557. XFE_ComposeView::createWidget(Widget )
  558.  
  559. {
  560.   Boolean wrap_p ;
  561.   {
  562.     // Create subviews
  563.     XFE_ComposeFolderView *view = 
  564.         new XFE_ComposeFolderView(getToplevel(), (XFE_View*)this, 
  565.             (MSG_Pane*)getPane(),getContext());
  566.  
  567.     view->createWidgets(getBaseWidget(), m_plaintextP);
  568.  
  569.     addView(view); // Parent class owns this view via "add" operation
  570.     m_folderViewAlias = (XFE_View*) view;
  571.     XtVaSetValues( view->getBaseWidget(), 
  572.         XmNallowResize, True,  NULL);
  573.     view->show(); 
  574.  
  575.   }
  576.   {
  577.     // Creating the subject bar....
  578.  
  579.     Widget lowerForm = XmCreateForm(getBaseWidget(), 
  580.                                     "lowrPaneFormWidget", NULL, 0 );
  581.     XtVaSetValues(lowerForm, 
  582.                   XmNshadowThickness, 0,
  583.                   XmNmarginWidth, 0,
  584.                   XmNmarginHeight, 0,
  585.                   XmNnavigationType, XmTAB_GROUP, NULL );
  586.  
  587.     createSubjectBar(lowerForm);
  588.  
  589.     m_editorFormW = XmCreateFrame(lowerForm, 
  590.                                   "composeViewEditFormWidget", NULL, 0);
  591.  
  592.     XtVaSetValues(m_editorFormW, 
  593.                   XmNnavigationType, XmTAB_GROUP,
  594.                   XmNtopAttachment, XmATTACH_WIDGET,
  595.                   XmNtopWidget, m_subjectFormW,
  596.                   XmNtopOffset, 5,
  597.                   XmNbottomAttachment, XmATTACH_FORM,
  598.                   XmNleftAttachment, XmATTACH_FORM,
  599.                   XmNrightAttachment, XmATTACH_FORM, NULL);
  600.  
  601.     XtManageChild(m_editorFormW);
  602.     XtManageChild(lowerForm);
  603.   }
  604.   if (m_plaintextP)
  605.   {
  606.     // Create Plain Editor View
  607.     XFE_TextEditorView *view2 = 
  608.         new XFE_TextEditorView(getToplevel(),(XFE_View*) this,
  609.             (MSG_Pane*)getPane(), m_contextData);
  610.             
  611.     wrap_p = CONTEXT_DATA (m_contextData)->compose_wrap_lines_p;
  612.     view2->createWidgets(m_editorFormW, wrap_p);
  613.     addView(view2); // Parent class owns this view via "add" operation
  614.     m_textViewAlias = (XFE_View*) view2;
  615.     view2->show(); 
  616.  
  617.     // This is a hack...
  618.     //CONTEXT_DATA(m_contextData)->mcBodyText = m_textViewAlias->getBaseWidget();
  619.  
  620.     getToplevel()->registerInterest(
  621.     XFE_ComposeView::tabAfterSubject, this,
  622.         (XFE_FunctionNotification)tabToEditor_cb);
  623.    }
  624.   else
  625.   {
  626.     m_contextData->is_editor = True;
  627.     m_contextData->bIsComposeWindow = TRUE;
  628.  
  629.     // CONTEXT_DATA (m_contextData)->scrolled_width = 0;
  630.     // CONTEXT_DATA (m_contextData)->scrolled_height = 0;
  631.  
  632.     XFE_EditorView *view3 = 
  633.         new XFE_EditorView(getToplevel(), m_editorFormW,
  634.                    (XFE_View*) this, m_contextData);
  635.             
  636.     m_daW  = CONTEXT_DATA(m_contextData)->drawing_area;
  637.     m_topW = getToplevel()->getBaseWidget();
  638.  
  639. #ifdef DEBUG_rhess2
  640.     // XmNpreeditType, "overthespot",
  641.     // XmNpreeditType, "root",
  642.     // XmNpreeditType, "none",
  643.  
  644.     XtVaSetValues (m_topW,
  645.                    XmNpreeditType, "offthespot",
  646.                    0);
  647. #endif
  648.  
  649.     XtVaSetValues (XtParent(m_daW), 
  650.                    XmNborderWidth, 2, 
  651.                    XmNborderColor, 
  652.                    CONTEXT_DATA (m_contextData)->default_bg_pixel,
  653.                    0);
  654.  
  655.     XtVaSetValues (m_daW, 
  656.                    XmNtraversalOn, True,
  657.                    0);
  658.     
  659.     XtInsertEventHandler(m_daW,  FocusChangeMask, FALSE, 
  660.                          daFocusProc, this, XtListTail);
  661.     XtInsertEventHandler(m_topW, FocusChangeMask, FALSE, 
  662.                          topFocusProc, this, XtListTail);
  663.  
  664.     // wrap_p = CONTEXT_DATA (m_contextData)->compose_wrap_lines_p;
  665.  
  666.     addView(view3); // Parent class owns this view via "add" operation
  667.  
  668.     m_htmlViewAlias = (XFE_View*) view3;
  669.     view3->show(); 
  670.  
  671.     // This is a hack...
  672.     CONTEXT_DATA (m_contextData)->mcBodyText = NULL;
  673.  
  674.     getToplevel()->registerInterest(
  675.     XFE_ComposeView::tabAfterSubject, this,
  676.         (XFE_FunctionNotification)tabToEditor_cb);
  677.    
  678.     // getToplevel()->registerInterest(
  679.     //     XFE_AddressOutliner::tabPrev, this,
  680.     //    (XFE_FunctionNotification)tabToEditor_cb);
  681.   }
  682.  
  683.  
  684. }
  685.  
  686. XFE_CALLBACK_DEFN(XFE_ComposeView,afterRealizeWidget)(XFE_NotificationCenter *,
  687.                                  void *, void*)
  688. {
  689.   XmFontList fontList;
  690.   // fe_MailComposeWin_Activate(context);
  691.   fontList = (XmFontList)fe_GetFont (m_contextData, 3, LO_FONT_FIXED);
  692.   // Set the default font in the text widget
  693.   if (m_plaintextP)
  694.       ((XFE_TextEditorView*)m_textViewAlias)->setFont(fontList);
  695.   else {
  696.       // Register Action
  697.  
  698.       XtAppAddActions( fe_XtAppContext, cv_actions,  2);
  699.  
  700. #ifdef DEBUG_rhess
  701.       fprintf(stderr, "Editor::[ override ]\n");
  702. #endif
  703.  
  704.       XtVaSetValues(
  705.                     CONTEXT_DATA (m_contextData)->drawing_area, 
  706.                     XmNuserData, this, 0
  707.                     );
  708.       XtOverrideTranslations(
  709.                              CONTEXT_DATA (m_contextData)->drawing_area, 
  710.                              XtParseTranslationTable(cvTraverseTranslations)
  711.                              );
  712.  
  713.   }
  714.  
  715.   // Initialize widget now
  716.   initialize();
  717.  
  718.   // Get Font
  719.   //fe_SensitizeMenus (m_contextData);
  720.  
  721.   // Set focus to the appropriate place depending on our mode:
  722.   // If there's no recipient, the AddressOutliner will grab the focus.
  723.   const char * subject = MSG_GetCompHeader(getPane(),MSG_SUBJECT_HEADER_MASK);
  724.  
  725.   // If there's a recipient but no subject, put the focus in the
  726.   // subject field;
  727.   if (!subject || strlen(subject) <= 0)
  728.       {
  729.           XmProcessTraversal(m_subjectW, XmTRAVERSE_CURRENT);
  730.       }
  731.   else    // else shift keyboard focus into the editor
  732.       {
  733.           focusIn();
  734.       }
  735.  
  736.   MSG_SetCompBoolHeader(getPane(),MSG_ATTACH_VCARD_BOOL_HEADER_MASK, fe_globalPrefs.attach_address_card);
  737. }
  738.  
  739. Boolean
  740. XFE_ComposeView::isCommandEnabled(CommandType command, void *calldata,
  741.                                   XFE_CommandInfo* info)
  742. {
  743.   MSG_Pane *pane = getPane();
  744.  
  745.     if (pane && MSG_DeliveryInProgress(pane) && command != xfeCmdStopLoading)
  746.         return False;
  747.  
  748.     Widget destW= XmGetDestination(XtDisplay(getBaseWidget()));
  749.     Widget focusW= XmGetFocusWidget(getBaseWidget());
  750.     if ((command == xfeCmdWrapLongLines && !m_plaintextP)
  751.         )
  752.         return False;
  753.  
  754.     if (command == xfeCmdAttachAddressBookCard) {
  755.         XDEBUG(printf("XFE_ComposeView::isCommandEnabled(xfeCmdAttachAddressBookCard)\n"));
  756.         return TRUE;
  757.     }
  758.     else if ( (command == xfeCmdNewMessage )
  759.          || (command == xfeCmdSaveDraft)
  760.          || (command == xfeCmdQuoteOriginalText)
  761.          || (command == xfeCmdQuote)
  762.          || (command == xfeCmdAttach)
  763.          || (command == xfeCmdWrapLongLines)
  764.          || (command == xfeCmdEditPreferences)
  765.          || (command == xfeCmdSendMessageNow) 
  766.          || (command == xfeCmdSendMessageLater) 
  767.          || (command == xfeCmdSearchAddress) 
  768.          || (command == xfeCmdSetPriorityHighest)
  769.          || (command == xfeCmdSetPriorityHigh)
  770.          || (command == xfeCmdSetPriorityNormal)
  771.          || (command == xfeCmdSetPriorityLow)
  772.          || (command == xfeCmdSetPriorityLowest)
  773.          || (command == xfeCmdToggleAddressArea)
  774.          || (command == xfeCmdToggleFormatToolbar) )
  775.         return True;
  776.     else if ( command == xfeCmdDeleteItem ) {
  777.           if ( m_plaintextP ) {
  778.               return True;
  779.           }
  780.           else {
  781.               if ( m_focusW ) {
  782.                   if ( m_focusW != m_addrTypeW )
  783.                       if ((m_focusW == m_subjectW) || 
  784.                           (m_focusW == m_addrTextW)) {
  785.                           return True;
  786.                       }
  787.                       else {
  788.                           if (m_plaintextP) {
  789.                               // NOTE:  textEditorView handles this one...
  790.                               //
  791.                               XFE_TextEditorView* tev = 
  792.                                   (XFE_TextEditorView*)m_textViewAlias;
  793.                               return tev->isCommandEnabled(xfeCmdDelete,
  794.                                                            calldata,info);
  795.                           }
  796.                           else {
  797.                               return False;
  798.                           }
  799.                       }
  800.                   else
  801.                       return False;
  802.               }
  803.               else {
  804.                   XFE_EditorView *html = (XFE_EditorView*) m_htmlViewAlias;
  805.                   XFE_Command*    handler = html->getCommand(command);
  806.               
  807.                   if (handler != NULL) {
  808.                       return handler->isEnabled(html, info);
  809.                   }
  810.                   else {
  811.                       return False;
  812.                   }
  813.               }
  814.           }
  815.     }
  816.     else if ( command == xfeCmdUndo ) {
  817.         if ( m_plaintextP ) {
  818.             return False;
  819.         }
  820.         else {
  821.             if ( m_focusW ) {
  822.                 return False;
  823.             }
  824.             else {
  825.                 XFE_EditorView *html = (XFE_EditorView*) m_htmlViewAlias;
  826.                 XFE_Command*    handler = html->getCommand(command);
  827.               
  828.                 if (handler != NULL) {
  829.                     return handler->isEnabled(html, info);
  830.                 }
  831.                 else {
  832.                     return False;
  833.                 }
  834.             }
  835.         }
  836.     }
  837.     else if ( command == xfeCmdCut   ||
  838.               command == xfeCmdCopy ) {
  839.         // NOTE... [ this should only be enabled if there's a selection..
  840.         //
  841.         if ( m_focusW ) {
  842.             if (XmIsTextField( m_focusW )) {
  843.                 XmTextPosition left;
  844.                 XmTextPosition right;
  845.                 Boolean gotcha = False;
  846.  
  847.                 // NOTE: we disable Cut/Copy if we're in the type
  848.                 //       field of the AddressOutliner...
  849.                 //
  850.                 if (m_focusW != m_addrTypeW) {
  851.                     gotcha = XmTextFieldGetSelectionPosition(m_focusW, 
  852.                                                              &left, &right);
  853.                 }
  854.  
  855.                 if (gotcha) {
  856.                     return ((right - left) > 0);
  857.                 }
  858.                 else {
  859.                     return False;
  860.                 }
  861.             }
  862.             else {
  863.                 if (XmIsText ( m_focusW )) {
  864.                     XmTextPosition left;
  865.                     XmTextPosition right;
  866.                       
  867.                     Boolean gotcha = False;
  868.                       
  869.                     // NOTE: we disable Cut/Copy if we're in the type
  870.                     //       field of the AddressOutliner...
  871.                     //
  872.                     if (m_focusW != m_addrTypeW) {
  873.                         gotcha = XmTextGetSelectionPosition(m_focusW, 
  874.                                                             &left, &right);
  875.                     }
  876.  
  877.                     if (gotcha) {
  878.                         return ((right - left) > 0);
  879.                     }
  880.                     else {
  881.                         return False;
  882.                     }
  883.                 }
  884.                 else {
  885.                     return False;
  886.                 }
  887.             }
  888.         }
  889.         else {
  890.             if (m_plaintextP) {
  891.                 // WARNING... [ the focus isn't being set correctly
  892.                 //
  893. #ifdef DEBUG_rhess
  894.                 fprintf(stderr, "ERROR::[ m_focusW = NULL ]\n");
  895. #endif
  896.                 return False;
  897.             }
  898.             else {
  899.                 XFE_EditorView *html = (XFE_EditorView*) m_htmlViewAlias;
  900.                 XFE_Command*    handler = html->getCommand(command);
  901.               
  902.                 if (handler != NULL) {
  903.                     return handler->isEnabled(html, info);
  904.                 }
  905.                 else {
  906.                     return False;
  907.                 }
  908.             }
  909.         }
  910.     }
  911.     else if ( command == xfeCmdPaste ||
  912.               command == xfeCmdPasteAsQuoted ) {
  913.         if ( m_focusW ) {
  914.             // NOTE... [ disable pasteAsQuoted for non-editor widgets
  915.             //
  916.             if ( command == xfeCmdPasteAsQuoted ) {
  917.                 if ( m_focusW == m_subjectW ||
  918.                      m_focusW == m_addrTextW ||
  919.                      m_focusW == m_addrTypeW ) {
  920.                     return False;
  921.                 }
  922.             }
  923.             else {
  924.                 // NOTE... [ disable paste for the address type widget
  925.                 //
  926.                 if (m_focusW == m_addrTypeW) {
  927.                     return False;
  928.                 }
  929.             }
  930.         }
  931.         else {
  932.             if (m_plaintextP) {
  933.                 // WARNING... [ the focus isn't being set correctly
  934.                 //
  935. #ifdef DEBUG_rhess
  936.                 fprintf(stderr, "ERROR::[ m_focusW = NULL ]\n");
  937. #endif
  938.                 return False;
  939.             }
  940.         }
  941.  
  942.         if (m_plaintextP) {
  943.             // NOTE... [ we call the editor code to check the clipboard
  944.             //
  945.             int32 len;
  946.  
  947.             if (fe_EditorCanPasteCache(m_contextData, &len) ||
  948.                 fe_EditorCanPasteLocal(m_contextData, &len) ||
  949.                 fe_EditorCanPasteText (m_contextData, &len)) {
  950.                 return True;
  951.             }
  952.             else {
  953.                 return False;
  954.             }
  955.         }
  956.         else {
  957.             // NOTE... [ this should only be enabled if there's 
  958.             //         [ something to PASTE in the clipboard
  959.             //
  960.             XFE_EditorView *html = (XFE_EditorView*) m_htmlViewAlias;
  961.             XFE_Command*    handler = html->getCommand(xfeCmdPaste);
  962.               
  963.             if (handler != NULL) {
  964.                 return handler->isEnabled(html, info);
  965.             }
  966.             else {
  967.                 return False;
  968.             }
  969.         }
  970.     }
  971.     else if ((command == xfeCmdSelectAll)) {
  972.  
  973.         //    If we are a PlainText editor, pass onto TextEditorView..
  974.         if (m_plaintextP) {
  975.             XFE_TextEditorView* tev =
  976.                 (XFE_TextEditorView*)m_textViewAlias;
  977.             
  978.             return tev->isCommandEnabled(command, calldata, info);
  979.         }
  980.         
  981.         //    HTML.. SelectAll only works for the main work area.
  982.         else if (!m_plaintextP && (m_focusW == NULL)) {
  983.             
  984.             XFE_EditorView* hev = (XFE_EditorView*)m_htmlViewAlias;
  985.             XFE_Command*    handler = hev->getCommand(command);
  986.             
  987.             if (handler != NULL)
  988.                 return handler->isEnabled(hev, info);
  989.         }
  990.  
  991.         // ignore any other.
  992.         return False;
  993.     }
  994.     else if ( m_plaintextP && 
  995.               ((XFE_TextEditorView*)m_textViewAlias)->isCommandEnabled(command,calldata,info))
  996.         {
  997.             return True;
  998.         }
  999.     //    All other commands we pass to FolderView.
  1000.     else if (m_folderViewAlias->isCommandEnabled(command, calldata, info))
  1001.         return True;
  1002.     else 
  1003.         return XFE_MNView::isCommandEnabled(command, calldata, info);
  1004. }
  1005.  
  1006. Boolean
  1007. XFE_ComposeView::isCommandSelected(CommandType command, void * calldata, 
  1008.                                    XFE_CommandInfo* info)
  1009. {
  1010.     if ( command == xfeCmdSetPriorityHighest)
  1011.         return    ((XFE_ComposeFolderView*)m_folderViewAlias)
  1012.             ->isPrioritySelected(MSG_HighestPriority);
  1013.  
  1014.     else if ( command == xfeCmdSetPriorityHigh)
  1015.         return ((XFE_ComposeFolderView*)m_folderViewAlias)
  1016.             ->isPrioritySelected(MSG_HighPriority);
  1017.  
  1018.     else if ( command == xfeCmdSetPriorityNormal)
  1019.         return ((XFE_ComposeFolderView*)m_folderViewAlias)
  1020.             ->isPrioritySelected(MSG_NormalPriority);
  1021.  
  1022.     else if ( command == xfeCmdSetPriorityLow)
  1023.         return ((XFE_ComposeFolderView*)m_folderViewAlias)
  1024.             ->isPrioritySelected(MSG_LowPriority);
  1025.  
  1026.     else if ( command == xfeCmdSetPriorityLowest)
  1027.         return ((XFE_ComposeFolderView*)m_folderViewAlias)
  1028.             ->isPrioritySelected(MSG_LowestPriority);
  1029.  
  1030.     else if ( command == xfeCmdAttachAddressBookCard)
  1031.             {
  1032.                 XDEBUG(printf("XFE_ComposeView::isCommandEnabled(xfeCmdAttachAddressBookCard)\n"));
  1033.                 return MSG_GetCompBoolHeader(getPane(),MSG_ATTACH_VCARD_BOOL_HEADER_MASK);
  1034.             }
  1035.  
  1036.     else if ( command == xfeCmdWrapLongLines)
  1037.      {
  1038.         return CONTEXT_DATA (m_contextData)->compose_wrap_lines_p;
  1039.     }
  1040.     else 
  1041.         return XFE_MNView::isCommandSelected(command, calldata, info);
  1042. }
  1043.  
  1044.  
  1045. Boolean
  1046. XFE_ComposeView::handlesCommand(CommandType command, void* calldata, XFE_CommandInfo* info)
  1047. {
  1048. XDEBUG(    printf ("in XFE_ComposeView::handlesCommand(%s)\n", Command::getString(command));)
  1049.  
  1050.   if ((command == xfeCmdWrapLongLines && !m_plaintextP)
  1051.       )
  1052.       return False;
  1053.   if ( (command == xfeCmdNewMessage )
  1054.     || (command == xfeCmdSaveDraft)
  1055.     || (command == xfeCmdAddresseePicker)
  1056.     || (command == xfeCmdQuoteOriginalText)
  1057.     || (command == xfeCmdQuote)
  1058.     || (command == xfeCmdAttach)
  1059.     || (command == xfeCmdAttachAddressBookCard)
  1060.     || (command == xfeCmdEditPreferences)
  1061.       || (command == xfeCmdSendMessageNow) 
  1062.         || (command == xfeCmdSendMessageLater)
  1063.     || (command == xfeCmdWrapLongLines)
  1064.       || (command == xfeCmdUndo) 
  1065.       || (command == xfeCmdCut) 
  1066.       || (command == xfeCmdCopy) 
  1067.       || (command == xfeCmdPaste) 
  1068.     || (command == xfeCmdDelete)
  1069.       || (command == xfeCmdPasteAsQuoted) 
  1070.       || (command == xfeCmdDeleteItem) 
  1071.       || (command == xfeCmdSearchAddress) 
  1072.       || (command == xfeCmdSetPriorityHighest)
  1073.     || (command == xfeCmdSetPriorityHigh)
  1074.     || (command == xfeCmdSetPriorityNormal)
  1075.     || (command == xfeCmdSetPriorityLow)
  1076.     || (command == xfeCmdSetPriorityLowest)
  1077.     || (command == xfeCmdToggleAddressArea)
  1078.     || (command == xfeCmdToggleFormatToolbar) )
  1079.      return True;
  1080.   else if ( m_plaintextP && 
  1081.         ((XFE_TextEditorView*)m_textViewAlias)->handlesCommand(command,calldata,info))
  1082.   {
  1083.         return True;
  1084.   }
  1085.   else if (m_folderViewAlias->handlesCommand(command, calldata, info))
  1086.      return True;
  1087.   else 
  1088.     return XFE_MNView::handlesCommand(command, calldata, info);
  1089. }
  1090.  
  1091. char*
  1092. XFE_ComposeView::commandToString(CommandType cmd,
  1093.                                  void* calldata, XFE_CommandInfo* info)
  1094. {
  1095.     if (cmd == xfeCmdToggleFormatToolbar) {
  1096.  
  1097.         Widget widget = NULL;
  1098.         Boolean show = !m_format_toolbar->isShown();
  1099.         
  1100.         if (info != NULL)
  1101.             widget = info->widget;
  1102.  
  1103.         return getShowHideLabelString(cmd, show, widget);
  1104.  
  1105.     } else if (cmd == xfeCmdToggleAddressArea) {
  1106.  
  1107.         Widget widget = NULL;
  1108.         
  1109.         if (info != NULL)
  1110.             widget = info->widget;
  1111.  
  1112.         return getShowHideLabelString(cmd, !m_expanded, widget);
  1113.  
  1114.     } else 
  1115.     
  1116.     return XFE_MNView::commandToString(cmd, calldata, info);
  1117. }
  1118.  
  1119.  
  1120. XFE_Command*
  1121. XFE_ComposeView::getCommand(CommandType cmd)
  1122. {
  1123.     if (m_plaintextP) {
  1124.         return NULL;
  1125.     } else {
  1126.         if ( cmd == xfeCmdCut   ||
  1127.              cmd == xfeCmdCopy  ||
  1128.              cmd == xfeCmdPaste ||
  1129.              cmd == xfeCmdDeleteItem ||
  1130.              cmd == xfeCmdSelectAll ||
  1131.              cmd == xfeCmdUndo ) {
  1132.             return NULL;
  1133.         }
  1134.         else
  1135.             return ((XFE_EditorView*)m_htmlViewAlias)->getCommand(cmd);
  1136.     }
  1137. }
  1138.  
  1139. XP_Bool
  1140. XFE_ComposeView::continueAfterSanityCheck()
  1141. {
  1142.   int errcode = 0;
  1143.   XP_Bool cont = True;
  1144.  
  1145.   errcode = MSG_SanityCheck(getPane(),errcode);
  1146.  
  1147.   XDEBUG( printf("Send Now error code is %d\n", errcode);)
  1148.   if ( errcode == MK_MSG_EMPTY_MESSAGE )
  1149.   {
  1150.         cont = XFE_Confirm(m_contextData,XP_GetString(errcode));
  1151.   }
  1152.   else if ( errcode == MK_MSG_DOUBLE_INCLUDE) 
  1153.   {
  1154.         cont = XFE_Confirm(m_contextData,XP_GetString(errcode));
  1155.   }
  1156.   else if ( errcode == MK_MSG_MIXED_SECURITY ) 
  1157.   {
  1158.         cont = XFE_Confirm(m_contextData,XP_GetString(errcode));
  1159.   }
  1160.   else if ( errcode == MK_MSG_MISSING_SUBJECT ) 
  1161.   {
  1162.         const char *def = XP_GetString(XFE_NO_SUBJECT);
  1163.         char *subject = (char *) fe_dialog (CONTEXT_WIDGET(m_contextData),
  1164.                              "promptSubject",
  1165.                              0, TRUE, def, TRUE, TRUE, 0);
  1166.  
  1167.         if ( subject && strlen(subject) )
  1168.         {
  1169.             fe_SetTextFieldAndCallBack(m_subjectW, subject);
  1170.  
  1171.             MSG_SetCompHeader(getPane(),MSG_SUBJECT_HEADER_MASK,subject);
  1172.             XtFree(subject);
  1173.         }
  1174.         else if ( !subject )
  1175.         {
  1176.       cont = False;
  1177.         }
  1178.    }
  1179.    return cont;
  1180. }
  1181.  
  1182. void
  1183. XFE_ComposeView::doCommand(CommandType command, void * calldata, XFE_CommandInfo* info)
  1184. {
  1185.   char *pBody;
  1186.   uint32 bodySize;
  1187.   MSG_FontCode *font_changes;
  1188.   int errcode = 0;
  1189.   Widget destW= XmGetDestination(XtDisplay(getBaseWidget()));
  1190.   Widget focusW= XmGetFocusWidget(getBaseWidget());
  1191.  
  1192. XDEBUG(    printf ("in XFE_ComposeView::doCommand()\n");)
  1193. XDEBUG(    printf ("Do Command: %s \n", Command::getString(command));)
  1194.  
  1195.   if (command == xfeCmdSendMessageNow)
  1196.     {
  1197.       XDEBUG(    printf ("XFE_ComposeView::sendMessageNow()\n");)
  1198.  
  1199.       updateHeaderInfo ( );
  1200.  
  1201.       MSG_SetHTMLMarkup(getPane(), !m_plaintextP);
  1202.  
  1203.       FE_GetMessageBody(getPane(), &pBody, &bodySize, &font_changes);
  1204.       //if ( bodySize)
  1205.         MSG_SetCompBody(getPane(), pBody );
  1206.  
  1207.       XP_FREE(pBody);
  1208.  
  1209.       if ( !continueAfterSanityCheck()) return;
  1210.  
  1211.       MSG_CommandType msg_cmd = MSG_SendMessage;
  1212.  
  1213. #if 0
  1214.       // For now, this flag was always set to true which is incorrect
  1215.       if( fe_globalPrefs.queue_for_later_p )
  1216.              msg_cmd = MSG_SendMessageLater;
  1217. #endif
  1218.  
  1219.       /* ###tw  Should still probably do the commandstatus stuff. */
  1220.       MSG_Command(getPane(), msg_cmd, NULL, 0);
  1221.     }
  1222.   else if (command == xfeCmdSendMessageLater)
  1223.     {
  1224.       XDEBUG(    printf ("XFE_ComposeView::sendMessageLater()\n");)
  1225.  
  1226.       updateHeaderInfo ( );
  1227.  
  1228.       FE_GetMessageBody(getPane(), &pBody, &bodySize, &font_changes);
  1229.       //if ( bodySize)
  1230.         MSG_SetCompBody(getPane(), pBody );
  1231.  
  1232.       XP_FREE(pBody);
  1233.  
  1234.       while ((errcode = MSG_SanityCheck(getPane(),errcode))!=0)
  1235.       {
  1236.         XDEBUG( printf("Send Later error code is %d\n", errcode);)
  1237.         if (!XFE_Confirm(m_contextData,XP_GetString(errcode)))
  1238.             return;
  1239.       }
  1240.       // Mark this to be true so that when ComposeFame deletion
  1241.       // happened, it will delete the ComposeFrame accordingly
  1242.       m_delayedSent = True;
  1243.       /* ###tw  Should still probably do the commandstatus stuff. */
  1244.       MSG_Command(getPane(), MSG_SendMessageLater, NULL, 0);
  1245.     }
  1246.   else if (command == xfeCmdSaveDraft)
  1247.   {
  1248.       XDEBUG(   printf ("XFE_ComposeView::saveAsDraft()\n");)
  1249.  
  1250.       updateHeaderInfo ( );
  1251.  
  1252.       FE_GetMessageBody(getPane(), &pBody, &bodySize, &font_changes);
  1253.       //if ( bodySize)
  1254.         MSG_SetCompBody(getPane(), pBody );
  1255.  
  1256.       XP_FREE(pBody);
  1257.  
  1258.       /* ###tw  Should still probably do the commandstatus stuff. */
  1259.     
  1260.       MSG_Command(getPane(), MSG_SaveDraft, NULL, 0);
  1261.  
  1262.      // Reset these two flags so that if user close the window, they
  1263.      // will not be prompt to save again
  1264.      CONTEXT_DATA(m_contextData)->mcCitedAndUnedited = True;
  1265.      CONTEXT_DATA(m_contextData)->mcEdited = False;
  1266.   }
  1267.   else if (command == xfeCmdEditPreferences)
  1268.   {
  1269.       fe_showMailNewsPreferences(getToplevel(), (MWContext*)m_contextData);
  1270.   }
  1271.   else if (command == xfeCmdQuoteOriginalText||
  1272.        command == xfeCmdQuote)
  1273.   {
  1274.       if (m_plaintextP) {
  1275.           Widget textW = CONTEXT_DATA(m_contextData)->mcBodyText;
  1276.  
  1277.           XtSetSensitive(textW, False);
  1278.           MSG_QuoteMessage (getPane(), &XFE_ComposeView::doQuoteMessage, this);
  1279.           XtSetSensitive(textW, True);
  1280.       }
  1281.       else {
  1282. #ifdef DEBUG_rhess
  1283.           if (command == xfeCmdQuote)
  1284.               fprintf(stderr, "xfeCmdQuote\n");
  1285.           else
  1286.               fprintf(stderr, "xfeCmdQuoteOriginalText\n");
  1287. #endif
  1288.           MSG_SetHTMLMarkup(getPane(), TRUE);
  1289.           MSG_QuoteMessage (getPane(), &XFE_ComposeView::doQuoteMessage, this);
  1290.       }
  1291.   }
  1292.   else if ( command == xfeCmdUndo )
  1293.   {
  1294.       if (!m_plaintextP) {
  1295.           XFE_EditorView* hev = (XFE_EditorView*)m_htmlViewAlias;
  1296.           XFE_Command*    handler = hev->getCommand(command);
  1297.       
  1298.           if (handler != NULL) {
  1299.               handler->doCommand(hev, info);
  1300.           }
  1301.       }
  1302.   }
  1303.   else if ( command == xfeCmdCut )
  1304.   {
  1305.       if (m_plaintextP) {
  1306.           fe_cut_cb(CONTEXT_WIDGET (m_contextData),
  1307.                     (XtPointer) m_contextData, NULL);
  1308.       }
  1309.       else {
  1310.           if (m_focusW == NULL) {
  1311.               // NOTE:  pass this command to the EditorView...
  1312.               //
  1313. #ifdef DEBUG_rhess
  1314.               fprintf(stderr, "xfeCmdCut::[ HTML ]\n");
  1315. #endif
  1316.               XFE_EditorView* hev = (XFE_EditorView*)m_htmlViewAlias;
  1317.               XFE_Command*    handler = hev->getCommand(command);
  1318.  
  1319.               if (handler != NULL) {
  1320.                   handler->doCommand(hev, info);
  1321.               }
  1322.           }
  1323.           else {
  1324. #ifdef DEBUG_rhess
  1325.               fprintf(stderr, "xfeCmdCut::[ plain ][ %p ]\n", focusW);
  1326. #endif
  1327.               m_focusW = focusW;
  1328.  
  1329.               fe_cut_cb(CONTEXT_WIDGET (m_contextData),
  1330.                         (XtPointer) m_contextData, NULL);
  1331.           }
  1332.       }
  1333.   }
  1334.   else if ( command == xfeCmdCopy )
  1335.   {
  1336.       if (m_plaintextP) {
  1337.           fe_copy_cb(CONTEXT_WIDGET (m_contextData),
  1338.                      (XtPointer) m_contextData, NULL);
  1339.       }
  1340.       else {
  1341.           if (m_focusW == NULL) {
  1342.               // NOTE:  pass this command to the EditorView...
  1343.               //
  1344. #ifdef DEBUG_rhess
  1345.               fprintf(stderr, "xfeCmdCopy::[ HTML ]\n");
  1346. #endif
  1347.               XFE_EditorView* hev = (XFE_EditorView*)m_htmlViewAlias;
  1348.               XFE_Command*    handler = hev->getCommand(command);
  1349.  
  1350.               if (handler != NULL) {
  1351.                   handler->doCommand(hev, info);
  1352.               }
  1353.           }
  1354.           else {
  1355. #ifdef DEBUG_rhess
  1356.               fprintf(stderr, "xfeCmdCopy::[ plain ][ %p ]\n", focusW);
  1357. #endif
  1358.               m_focusW = focusW;
  1359.  
  1360.               fe_copy_cb(CONTEXT_WIDGET (m_contextData),
  1361.                          (XtPointer) m_contextData, NULL);
  1362.           }
  1363.       }
  1364.   }
  1365.   else if ( command == xfeCmdPaste )
  1366.   {
  1367.       if (m_plaintextP) {
  1368.           fe_paste_cb(CONTEXT_WIDGET (m_contextData),
  1369.                       (XtPointer) m_contextData, NULL);
  1370.       }
  1371.       else {
  1372.           if ((m_focusW == NULL) || (info->widget == m_daW)) {
  1373.               Boolean handled = handleStealthPasteQuote(command, info);
  1374.  
  1375.               if (!handled) {
  1376.                   // NOTE:  pass this command to the EditorView...
  1377.                   //
  1378. #ifdef DEBUG_rhess
  1379.                   fprintf(stderr, "xfeCmdPaste::[ HTML ]\n");
  1380. #endif
  1381.                   XFE_EditorView* hev = (XFE_EditorView*)m_htmlViewAlias;
  1382.                   XFE_Command*    handler = hev->getCommand(command);
  1383.  
  1384.                   if (handler != NULL) {
  1385.                       handler->doCommand(hev, info);
  1386.                   }
  1387.               }
  1388.           }
  1389.           else {
  1390. #ifdef DEBUG_rhess
  1391.               fprintf(stderr, "xfeCmdPaste::[ plain ][ %p ]\n", focusW);
  1392. #endif
  1393.               m_focusW = focusW;
  1394.  
  1395.               fe_paste_cb(CONTEXT_WIDGET (m_contextData),
  1396.                           (XtPointer) m_contextData, NULL);
  1397.           }
  1398.       }
  1399.   }
  1400.   else if ( command == xfeCmdPasteAsQuoted )
  1401.   {
  1402.       if (m_plaintextP) {
  1403.           // This command will always make the textWidget to be the focus, 
  1404.           // per UI spec
  1405.           Widget textW = CONTEXT_DATA(m_contextData)->mcBodyText;
  1406.  
  1407.           XmProcessTraversal(textW, XmTRAVERSE_CURRENT);
  1408.  
  1409.           fe_paste_quoted_cb(CONTEXT_WIDGET (m_contextData),
  1410.                              (XtPointer) m_contextData, NULL);
  1411.       }
  1412.       else {
  1413.           Boolean handled = handleStealthPasteQuote(command, info);
  1414.  
  1415.           if (!handled) {
  1416.               int32   internal  = 0;
  1417.               char*   clip_data = NULL;
  1418.  
  1419.               clip_data = xfe2_GetClipboardText(focusW, &internal);
  1420.  
  1421.               if (clip_data) {
  1422.                   MSG_PastePlaintextQuotation(getPane(), clip_data);
  1423.                   XP_FREE(clip_data);
  1424.               }
  1425.           }
  1426.       }
  1427.   }
  1428.   else if ( command == xfeCmdSetPriorityHighest )
  1429.   {
  1430.     // Set Priority
  1431.     ((XFE_ComposeFolderView*)m_folderViewAlias)
  1432.             ->selectPriority(MSG_HighestPriority);
  1433.   }
  1434.   else if ( command == xfeCmdSetPriorityHigh )
  1435.   {
  1436.     // Set Priority
  1437.     ((XFE_ComposeFolderView*)m_folderViewAlias)
  1438.         ->selectPriority(MSG_HighPriority);
  1439.   }
  1440.   else if ( command == xfeCmdSetPriorityNormal )
  1441.   {
  1442.     // Set Priority
  1443.     ((XFE_ComposeFolderView*)m_folderViewAlias)
  1444.         ->selectPriority(MSG_NormalPriority);
  1445.   }
  1446.   else if ( command == xfeCmdSetPriorityLow )
  1447.   {
  1448.     // Set Priority
  1449.     ((XFE_ComposeFolderView*)m_folderViewAlias)
  1450.         ->selectPriority(MSG_LowPriority);
  1451.   }
  1452.   else if ( command == xfeCmdSetPriorityLowest )
  1453.   {
  1454.     // Set Priority
  1455.     ((XFE_ComposeFolderView*)m_folderViewAlias)
  1456.         ->selectPriority(MSG_LowestPriority);
  1457.   }
  1458.   else if ( command == xfeCmdWrapLongLines )
  1459.   {
  1460.         XP_Bool state = CONTEXT_DATA (m_contextData)->compose_wrap_lines_p;
  1461.     setComposeWrapState(!state);    
  1462.   }
  1463.   else if ( command == xfeCmdAttachAddressBookCard )
  1464.   {
  1465.       // toggle compose header flag
  1466.       XP_Bool state=MSG_GetCompBoolHeader(getPane(),MSG_ATTACH_VCARD_BOOL_HEADER_MASK);
  1467.       MSG_SetCompBoolHeader(getPane(),MSG_ATTACH_VCARD_BOOL_HEADER_MASK, state ? FALSE : TRUE);
  1468.   }
  1469.   else if ( command == xfeCmdViewAddresses ||
  1470.     command == xfeCmdAttachFile ||
  1471.     command == xfeCmdAttachWebPage ||
  1472.     command == xfeCmdDeleteAttachment ||
  1473.     command == xfeCmdViewOptions ||
  1474.     command == xfeCmdViewAttachments ||
  1475.     command == xfeCmdAddresseePicker    )
  1476.   {
  1477.     if ( m_folderViewAlias )
  1478.         m_folderViewAlias->doCommand(command, calldata, info);
  1479.   }
  1480.   else if (command == xfeCmdToggleFormatToolbar)
  1481.   {
  1482.     m_format_toolbar->toggle();
  1483.   }
  1484.   else if (command == xfeCmdToggleAddressArea)
  1485.   {
  1486.       toggleAddressArea();
  1487.   }
  1488.   else if (command == xfeCmdViewSecurity ) 
  1489.   {
  1490.            updateHeaderInfo();
  1491.            fe_sec_logo_cb(NULL, getContext(), NULL);
  1492.   }
  1493.   else if (command == xfeCmdDeleteItem) {
  1494.       if ( m_focusW ) {
  1495.           if ( m_focusW != m_addrTypeW ) {
  1496.               if ((m_focusW == m_subjectW) || 
  1497.                   (m_focusW == m_addrTextW)) {
  1498.                   // NOTE:  Xt handles the simple text widgets...
  1499.                   //
  1500.                   XEvent *event = info->event;
  1501.                   XtCallActionProc(m_focusW, 
  1502.                                    "delete-next-character", 
  1503.                                    event, NULL, 0 );
  1504.               }
  1505.               else {
  1506.                   if (m_plaintextP) {
  1507.                       // NOTE:  textEditorView handles this one...
  1508.                       //
  1509.                       XFE_TextEditorView* tev =
  1510.                           (XFE_TextEditorView*)m_textViewAlias;
  1511.  
  1512.                       tev->doCommand(xfeCmdDelete, calldata, info);
  1513.                   }
  1514.                   else {
  1515.                       // NOTE:  we shouldn't ever get here...
  1516.                       //
  1517.                   }
  1518.               }
  1519.           }
  1520.       }
  1521.       else {
  1522.           XFE_EditorView* hev = (XFE_EditorView*)m_htmlViewAlias;
  1523.           XFE_Command*    handler = hev->getCommand(command);
  1524.  
  1525.           if (handler != NULL) {
  1526.               handler->doCommand(hev, info);
  1527.           }
  1528.       }
  1529.   }
  1530.   else if ((command == xfeCmdSelectAll)) {
  1531.       //    If we are a PlainText editor, pass onto TextEditorView..
  1532.       if (m_plaintextP) {
  1533.           XFE_TextEditorView* tev =
  1534.               (XFE_TextEditorView*)m_textViewAlias;
  1535.           
  1536.           tev->doCommand(command, calldata,    info);
  1537.       }
  1538.  
  1539.       //    HTML.. SelectAll only works for the main work area.
  1540.       else if (!m_plaintextP && m_focusW == NULL) {
  1541.           
  1542.           XFE_EditorView* hev = (XFE_EditorView*)m_htmlViewAlias;
  1543.           XFE_Command*    handler = hev->getCommand(command);
  1544.           
  1545.           if (handler != NULL)
  1546.               handler->doCommand(hev, info);
  1547.  
  1548.       } // ignore any other.
  1549.   }
  1550.   else if ( (m_plaintextP ) && 
  1551.     ((XFE_TextEditorView*)m_textViewAlias)->isCommandEnabled(command,calldata,info))
  1552.  
  1553.       ((XFE_TextEditorView*)m_textViewAlias)->doCommand(command,calldata,info);
  1554.   else if ( (m_folderViewAlias ) && 
  1555.     ((XFE_ComposeFolderView*)m_folderViewAlias)->isCommandEnabled(command,calldata,info))
  1556.  
  1557.       ((XFE_ComposeFolderView*)m_folderViewAlias)->doCommand(command,calldata,info);
  1558.   else
  1559.   {
  1560.     XFE_MNView::doCommand(command, calldata, info);
  1561.   }
  1562. }
  1563.  
  1564. XP_Bool
  1565. XFE_ComposeView::handleStealthPasteQuote(CommandType cmd, XFE_CommandInfo* info)
  1566. {
  1567.     Widget   base = getBaseWidget();
  1568.     Display *dpy  = XtDisplay(base);
  1569.     Window   rat  = XGetSelectionOwner(dpy, XA_PRIMARY);
  1570.     XP_Bool  stealth = False;
  1571.  
  1572.     // NOTE... [ special handling required to support both menu and mouse
  1573.     //         [ click enabling of this feature...
  1574.     //
  1575.     if (rat != None) {
  1576.         if (info && 
  1577.             info->event &&
  1578.             (((info->event->type == ButtonRelease) && 
  1579.               (cmd == xfeCmdPasteAsQuoted)) ||
  1580.              ((info->event->type == ButtonPress) && 
  1581.               (cmd == xfeCmdPaste))
  1582.             ) &&
  1583.             (info->event->xkey.state & ShiftMask)) {
  1584.             stealth = True;
  1585.         }
  1586.     }
  1587.  
  1588.     if (stealth) {
  1589.         Time timestamp = info->event->xbutton.time;
  1590.         
  1591.         // NOTE... [ if it's triggered off a mouse click (Btn2), 
  1592.         //         [ set the location before you paste...
  1593.         //
  1594.         if ((info->event->type == ButtonPress) &&
  1595.             (cmd == xfeCmdPaste)
  1596.             ) {
  1597.             fe_EditorGrabFocus(m_contextData, info->event);
  1598.         }
  1599.  
  1600.         /*
  1601.          *  NOTE:  only works if we are talking to one server... [ oops ]
  1602.          */
  1603.         if (XFE_TEXT_ATOM == 0)
  1604.             XFE_TEXT_ATOM = XmInternAtom(dpy, "STRING", False);
  1605.         
  1606.         /*
  1607.          *  NOTE:  only paste text from primary selection...
  1608.          */
  1609.         XtGetSelectionValue(base, 
  1610.                             XA_PRIMARY, XFE_TEXT_ATOM, 
  1611.                             quotePrimarySel_cb, 
  1612.                             (XtPointer) this, 
  1613.                             timestamp);
  1614.     }
  1615.  
  1616.     return stealth;
  1617. }
  1618.  
  1619. void*
  1620. XFE_ComposeView::getComposerData()
  1621. {
  1622.     return mailComposer;
  1623. }
  1624.  
  1625. void
  1626. XFE_ComposeView::setComposerData(void* data)
  1627. {
  1628.     mailComposer= data;
  1629. }
  1630.  
  1631. void*
  1632. XFE_ComposeView::getAttachmentData()
  1633. {
  1634.     return mailAttachment;
  1635. }
  1636.  
  1637. void
  1638. XFE_ComposeView::setAttachmentData(void* data)
  1639. {
  1640.     mailAttachment= data;
  1641. }
  1642.  
  1643.  
  1644.  
  1645. extern "C" void 
  1646. fe_MailComposeDocumentLoaded(MWContext* context)
  1647. {
  1648.     XtPointer     client = NULL;
  1649.     XFE_ComposeView *obj = NULL;
  1650.     Widget            da = NULL;
  1651.  
  1652. #ifdef DEBUG_rhess2
  1653.     fprintf(stderr, "ComposeView::[ fe_MailComposeGetURLExitRoutine ]\n");
  1654. #endif
  1655.  
  1656.     da = CONTEXT_DATA(context)->drawing_area;
  1657.     if (da) {
  1658.         XtVaGetValues(da, XmNuserData, &client, 0);
  1659.  
  1660.         obj = (XFE_ComposeView *) client;
  1661.         obj->initEditorContents();
  1662.     }
  1663. }
  1664.  
  1665. extern "C" void *
  1666. fe_compose_getData(MWContext *context)
  1667. {
  1668.   XFE_Frame *f = ViewGlue_getFrame(context);
  1669.  
  1670.   XP_ASSERT(f->getType() == FRAME_MAILNEWS_COMPOSE);
  1671.  
  1672.   return ((XFE_ComposeView *)f->getView())->getComposerData();
  1673. }
  1674.  
  1675. extern "C" void
  1676. fe_compose_setData(MWContext *context, void* data)
  1677. {
  1678.   XFE_Frame *f = ViewGlue_getFrame(context);
  1679.   
  1680.   XP_ASSERT(f->getType() == FRAME_MAILNEWS_COMPOSE);
  1681.   
  1682.   ((XFE_ComposeView *)f->getView())->setComposerData(data);
  1683. }
  1684.  
  1685. extern "C" void *
  1686. fe_compose_getAttachment(MWContext *context)
  1687. {
  1688.   XFE_Frame *f = ViewGlue_getFrame(context);
  1689.   
  1690.   XP_ASSERT(f->getType() == FRAME_MAILNEWS_COMPOSE);
  1691.   
  1692.   return ((XFE_ComposeView *)f->getView())->getAttachmentData();
  1693. }
  1694.  
  1695. extern "C" void
  1696. fe_compose_setAttachment(MWContext *context, void* data)
  1697. {
  1698.   XFE_Frame *f = ViewGlue_getFrame(context);
  1699.   
  1700.   XP_ASSERT(f->getType() == FRAME_MAILNEWS_COMPOSE);
  1701.   
  1702.   ((XFE_ComposeView *)f->getView())->setAttachmentData(data);
  1703. }
  1704.  
  1705.  
  1706. // ------------ NEW CODE ----------------------
  1707.  
  1708. int
  1709. XFE_ComposeView::quoteMessage(const char *textData)
  1710. {
  1711.   if (textData != NULL)
  1712.   {
  1713. #ifdef DEBUG_rhess
  1714.       fprintf(stderr, "quoteMessage\n");
  1715. #endif
  1716.       insertMessageCompositionText( textData, False);
  1717.   }
  1718.   return 0;
  1719. }
  1720.  
  1721. int
  1722. XFE_ComposeView::doQuoteMessage(void *closure, const char *textData)
  1723. {
  1724.  XFE_ComposeView *obj = (XFE_ComposeView *)closure;
  1725.  
  1726.  XP_ASSERT(obj != NULL);
  1727.  
  1728. #ifdef DEBUG_rhess
  1729.    fprintf(stderr, "doQuoteMessage\n");
  1730. #endif
  1731.  
  1732.  // Requires to return negative value on error
  1733.  return obj->quoteMessage(textData);
  1734. }
  1735.  
  1736. void
  1737. XFE_ComposeView::displayDefaultTextBody()
  1738. {
  1739.      MSG_Pane *pane = getPane(); // Get it from MNView
  1740.      const char *pBody = MSG_GetCompBody(pane);
  1741.  
  1742.      if ( m_pInitialText && XP_STRLEN(m_pInitialText) ) {
  1743.          insertMessageCompositionText( m_pInitialText, False);
  1744.  
  1745.          if (m_plaintextP)
  1746.              insertMessageCompositionText( "\n", False);
  1747.  
  1748.          XP_FREEIF(m_pInitialText);
  1749.  
  1750.          m_dontQuoteP = True;
  1751. #ifdef DEBUG_rhess
  1752.          fprintf(stderr, "  m_dontQuoteP... [ True ]\n");
  1753. #endif
  1754.      }
  1755.      else {
  1756.          if ( pBody && strlen(pBody) ) {
  1757.              insertMessageCompositionText( pBody, False);
  1758.  
  1759.              m_dontQuoteP = False;
  1760. #ifdef DEBUG_rhess
  1761.              fprintf(stderr, "  m_dontQuoteP... [ False ]\n");
  1762. #endif
  1763.          }
  1764.          else {
  1765.              if (m_plaintextP) {
  1766.                  // NOTE:  skip over this for plaintext...
  1767.                  //
  1768.              }
  1769.              else {
  1770.                  // NOTE:  we need this to handle the special case where there 
  1771.                  //        isn't any default text for the message...
  1772.                  //
  1773. #ifdef DEBUG_rhess
  1774.                  fprintf(stderr, "displayDefaultTextBody::[ NULL ]\n");
  1775. #endif
  1776.                  xfe2_EditorInit(m_contextData);
  1777.              }
  1778.          }
  1779.      }
  1780. }
  1781.  
  1782. // Inserting initial addressing field value
  1783. void
  1784. XFE_ComposeView::initialize()
  1785. {
  1786.     MSG_Pane *pane = getPane(); // Get it from MNView
  1787.     Widget textW = NULL;
  1788.  
  1789.     if (m_plaintextP) {
  1790.         XmTextPosition cPos = 0;
  1791.  
  1792.         textW = CONTEXT_DATA(m_contextData)->mcBodyText;
  1793.  
  1794.         XtSetSensitive(textW, False);
  1795.  
  1796.         MSG_SetHTMLMarkup(pane, !m_plaintextP);
  1797.  
  1798.         if ( m_pInitialText && XP_STRLEN(m_pInitialText) ) {
  1799.             m_dontQuoteP = True;
  1800.         }
  1801.         else {
  1802.             m_dontQuoteP = False;
  1803.         }
  1804.  
  1805.         if ( !m_dontQuoteP && MSG_ShouldAutoQuote (pane) ) {
  1806.             MSG_QuoteMessage (pane, &XFE_ComposeView::doQuoteMessage, this);
  1807.         }
  1808.  
  1809.         cPos = XmTextGetLastPosition(textW);
  1810.  
  1811.         XmTextSetCursorPosition(textW, cPos);
  1812.  
  1813.         displayDefaultTextBody();
  1814.          
  1815.         XmTextSetCursorPosition(textW, cPos);
  1816.  
  1817.         XtSetSensitive(textW, True);
  1818.     }
  1819.     else {
  1820.         // NOTE: do all this work in XFE_ComposeView::initEditor()...
  1821.         //
  1822.     }
  1823. }
  1824.  
  1825. XP_Bool
  1826. XFE_ComposeView::hasFocus()
  1827. {
  1828.     return m_editorFocusP;
  1829. }
  1830.  
  1831. void 
  1832. XFE_ComposeView::daFocusProc(Widget,XtPointer cd,XEvent *event,Boolean*)
  1833. {
  1834.     // NOTE: event handler on the drawing area...
  1835.     //
  1836.     XFE_ComposeView *obj = (XFE_ComposeView*)cd;
  1837.  
  1838. #ifdef DEBUG_rhess_NOT
  1839.     if (!event->xfocus.send_event)
  1840.         {
  1841.             fprintf(stderr, "++---------------------------------[ synth ]\n");
  1842.         }
  1843. #endif
  1844.  
  1845.     if (event->type == FocusIn)
  1846.         {
  1847.             obj->focusIn();
  1848.         }
  1849.     else
  1850.         {
  1851.             obj->focusOut();
  1852.         }
  1853. }
  1854.  
  1855. void 
  1856. XFE_ComposeView::topFocusProc(Widget,XtPointer cd,XEvent *event,Boolean*)
  1857. {
  1858.     // NOTE: event handler on the toplevel shell...
  1859.     //
  1860.     XFE_ComposeView *obj = (XFE_ComposeView*)cd;
  1861.  
  1862.     if (event->type == FocusIn)
  1863.         {
  1864.             // NOTE:  we don't need to do anything here since the 
  1865.             //        nullFocusProc event handler on m_nullW will
  1866.             //        auto-magically set the focus to the editor...
  1867.             //
  1868.         }
  1869.     else
  1870.         {
  1871.             obj->saveFocus();
  1872.         }
  1873. }
  1874.  
  1875. void 
  1876. XFE_ComposeView::nullFocusProc(Widget,XtPointer cd,XEvent *event,Boolean*)
  1877. {
  1878.     // NOTE: event handler on the "null" widget...
  1879.     //
  1880.     XFE_ComposeView *obj = (XFE_ComposeView*)cd;
  1881.  
  1882.     if (event->type == FocusIn)
  1883.         {
  1884. #ifdef DEBUG_rhess2
  1885.             fprintf(stderr, "null::[ FocusIn ]\n");
  1886. #endif
  1887.             obj->focusIn();
  1888.         }
  1889.     else 
  1890.         {
  1891. #ifdef DEBUG_rhess2    
  1892.             fprintf(stderr, "null::[ FocusOut ]\n");
  1893. #endif
  1894.         }
  1895. }
  1896.  
  1897. void
  1898. XFE_ComposeView::saveFocus()
  1899. {
  1900.     Widget who = XmGetFocusWidget(m_topW);
  1901.  
  1902.     if (who) {
  1903.         // NOTE:  don't mess with m_focusW unless we've lost focus 
  1904.         //        in the editor...
  1905.         if (who == m_nullW) {
  1906.             m_focusW = NULL;
  1907.         }
  1908.     }
  1909. }
  1910.  
  1911. void
  1912. XFE_ComposeView::focusIn()
  1913. {
  1914.     if (m_plaintextP) {
  1915.         Widget textW = CONTEXT_DATA(m_contextData)->mcBodyText;
  1916.         XmProcessTraversal(textW, XmTRAVERSE_CURRENT);
  1917.  
  1918.         m_focusW = textW;
  1919.     }
  1920.     else {
  1921.         if (!m_editorFocusP) {
  1922.             m_editorFocusP = True;
  1923.             
  1924.             XtVaSetValues (XtParent(m_daW), XmNborderColor,
  1925.                            CONTEXT_DATA (m_contextData)->default_fg_pixel,
  1926.                            0);
  1927.                 
  1928.             xfe2_EditorCaretShow(m_contextData);
  1929.             
  1930.             XmProcessTraversal(m_topW, XmTRAVERSE_CURRENT);
  1931.             
  1932.             // NOTE:  if there's any "magic" in this whole focus mechanism,
  1933.             //        it's right here...
  1934.             //
  1935.             Widget who = XmGetFocusWidget(m_topW);
  1936.  
  1937.             if (m_nullW) {
  1938.                 if (m_nullW != who) {
  1939. #ifdef DEBUG_rhess
  1940.                     fprintf(stderr, "yikes... [ new m_nullW value ]\n");
  1941. #endif
  1942.                     XtRemoveEventHandler(m_nullW,  FocusChangeMask, 
  1943.                                          FALSE, nullFocusProc, this);
  1944.                     XtInsertEventHandler(who,  FocusChangeMask, FALSE, 
  1945.                                          nullFocusProc, this, XtListTail);
  1946.                 }
  1947.             }
  1948.             else {
  1949.                 XtInsertEventHandler(who,  FocusChangeMask, FALSE, 
  1950.                                      nullFocusProc, this, XtListTail);
  1951.             }
  1952.  
  1953.             m_nullW  = who;
  1954.             m_focusW = NULL;
  1955.             
  1956.             if (fe_globalData.editor_im_input_enabled) {
  1957.                 xfe2_EditorImSetCoords(m_contextData);
  1958.             }
  1959.  
  1960.             XtSetKeyboardFocus(m_topW, m_daW);
  1961.         }
  1962.     }
  1963. }
  1964.  
  1965. void
  1966. XFE_ComposeView::focusOut()
  1967. {
  1968.     Widget who = XmGetFocusWidget(m_topW);
  1969.  
  1970.     if (m_plaintextP) {
  1971.         // YOH:  any idea if we need to do something here?...
  1972.         //
  1973.     }
  1974.     else {
  1975.         if (m_editorFocusP) {
  1976.             m_editorFocusP = False;
  1977.  
  1978.             xfe2_EditorCaretHide(m_contextData);
  1979.             
  1980.             if (fe_globalData.editor_im_input_enabled) {
  1981.                 XmImUnsetFocus(m_daW);
  1982.             }
  1983.  
  1984.             XtSetKeyboardFocus(m_topW, None);
  1985.  
  1986.             XtVaSetValues (XtParent(m_daW), XmNborderColor,
  1987.                            CONTEXT_DATA (m_contextData)->default_bg_pixel,
  1988.                            0);
  1989.             
  1990.             // XFlush(XtDisplay(m_subjectW));
  1991.             XmProcessTraversal(m_topW, XmTRAVERSE_CURRENT);
  1992.             XmProcessTraversal(who, XmTRAVERSE_CURRENT);
  1993.         }
  1994.     }
  1995. }
  1996.  
  1997. void
  1998. XFE_ComposeView::updateCompToolbar()
  1999. {
  2000.     char*            address;
  2001.     URL_Struct*      n_url;
  2002.  
  2003.     if (m_delayEditorP) {
  2004.         m_delayEditorP = False;
  2005.  
  2006. #ifdef DEBUG_rhess
  2007.             fprintf(stderr, "initEditor... [ about:editfilenew ]\n");
  2008. #endif
  2009.  
  2010.         // NOTE:  create a blank address...
  2011.         address = "about:editfilenew";
  2012.         n_url = NET_CreateURLStruct(address, NET_DONT_RELOAD);
  2013.  
  2014.         ((XFE_EditorView*)m_htmlViewAlias)->getURL(n_url, (n_url == NULL));
  2015.     }
  2016. }
  2017.  
  2018. int
  2019. XFE_ComposeView::initEditor()
  2020. {
  2021.     char*            address;
  2022.     URL_Struct*      n_url;
  2023.     int              rtn = 0;
  2024.  
  2025.     if ( m_plaintextP ) {
  2026.     }
  2027.     else {
  2028.         if (XP_IsContextBusy(m_contextData)) {
  2029. #ifdef DEBUG_rhess
  2030.             fprintf(stderr, "initEditor::[ delay ]\n");
  2031. #endif
  2032.             m_delayEditorP = True;
  2033.         }
  2034.         else {
  2035. #ifdef DEBUG_rhess
  2036.             fprintf(stderr, "initEditor\n");
  2037. #endif
  2038.             m_delayEditorP = False;
  2039.  
  2040.             // NOTE:  create a blank address...
  2041.             address = "about:editfilenew";
  2042.             n_url = NET_CreateURLStruct(address, NET_DONT_RELOAD);
  2043.  
  2044.             rtn = ((XFE_EditorView*)m_htmlViewAlias)->getURL(n_url, 
  2045.                                                              (n_url == NULL));
  2046.         }
  2047.     }
  2048.  
  2049.     return (rtn);
  2050. }
  2051.  
  2052.  
  2053. void
  2054. XFE_ComposeView::initEditorContents()
  2055. {
  2056.     MSG_Pane *pane = getPane(); // Get it from MNView
  2057.  
  2058.     if (m_puntEditorP) {
  2059. #ifdef DEBUG_rhess2
  2060.         fprintf(stderr, "initEditorContents::[ PUNT ]\n");
  2061. #endif
  2062.     }
  2063.     else {
  2064.         if (!m_initEditorP) {
  2065.             m_initEditorP = True;
  2066.  
  2067.             MSG_SetHTMLMarkup(pane, !m_plaintextP);
  2068.  
  2069.             // EDT_ReturnKey(m_contextData);
  2070.  
  2071.             // EDT_SelectAll(m_contextData);
  2072.             // EDT_ClearSelection(m_contextData);
  2073.  
  2074.             if ( m_pInitialText && XP_STRLEN(m_pInitialText) ) {
  2075.                 m_dontQuoteP = True;
  2076.             }
  2077.             else {
  2078.                 m_dontQuoteP = False;
  2079.             }
  2080.  
  2081.             EDT_BeginOfDocument(m_contextData, False);
  2082.  
  2083.             if ( !m_dontQuoteP && MSG_ShouldAutoQuote (pane) ) {
  2084. #ifdef DEBUG_rhess
  2085.                 fprintf(stderr, "initEditorContents::[ quote ]\n");
  2086. #endif
  2087.                 MSG_QuoteMessage (pane, 
  2088.                                   &XFE_ComposeView::doQuoteMessage, this);
  2089.             }
  2090.             else {
  2091. #ifdef DEBUG_rhess
  2092.                 fprintf(stderr, "initEditorContents::[ default ]\n");
  2093. #endif
  2094.                 m_postEditorP = True;
  2095.  
  2096.                 displayDefaultTextBody();
  2097.             }
  2098.         }
  2099.         else {
  2100.             if (!m_postEditorP) {
  2101. #ifdef DEBUG_rhess
  2102.                 fprintf(stderr, "initEditorContents::[ default ]\n");
  2103. #endif
  2104.                 m_postEditorP = True;
  2105.  
  2106.                 EDT_EndOfDocument(m_contextData, False);
  2107.  
  2108.                 displayDefaultTextBody();
  2109.             }
  2110.             else {
  2111. #ifdef DEBUG_rhess
  2112.                 fprintf(stderr, "initEditorContents::[ top ]\n");
  2113. #endif
  2114.                 m_puntEditorP = True;
  2115.                 
  2116.                 EDT_BeginOfDocument(m_contextData, False);
  2117.                 // NOTE:  we need to set this so that we can determine
  2118.                 //        if the user has changed the document from 
  2119.                 //        what we just loaded...
  2120.                 //
  2121.                 EDT_SetDirtyFlag(m_contextData, False);
  2122.  
  2123.                 fe_UserActivity(m_contextData);
  2124.         
  2125.                 xfe2_EditorInit(m_contextData);
  2126.             }
  2127.         }
  2128.     }
  2129. }
  2130.  
  2131. XFE_CALLBACK_DEFN(XFE_ComposeView,tabToEditor)(XFE_NotificationCenter*, void*, void*)
  2132. {
  2133. #ifdef DEBUG_rhess
  2134.   fprintf(stderr, "Editor::[ tabToEditor ]\n");
  2135. #endif
  2136.  
  2137.   focusIn();
  2138. }
  2139.  
  2140. void
  2141. XFE_ComposeView::insertMessageCompositionText(
  2142.         const char* text, XP_Bool leaveCursorBeginning)
  2143. {
  2144.     if (m_plaintextP) {
  2145.         ((XFE_TextEditorView*)m_textViewAlias)->
  2146.             insertMessageCompositionText(text, leaveCursorBeginning);
  2147.     }
  2148.     else {
  2149. #ifdef DEBUG_rhess2
  2150.         fprintf(stderr, "++\n%s\n++\n", text);
  2151. #endif
  2152.         ((XFE_EditorView*)m_htmlViewAlias)->
  2153.             insertMessageCompositionText(text, leaveCursorBeginning, 
  2154.                                          m_requestHTML);
  2155.     }
  2156. }
  2157.  
  2158. void 
  2159. XFE_ComposeView::getMessageBody(
  2160.         char **pBody, uint32 *body_size, 
  2161.         MSG_FontCode **font_changes)
  2162. {
  2163.     if (m_plaintextP) {
  2164.         ((XFE_TextEditorView*)m_textViewAlias)->
  2165.             getMessageBody(pBody, body_size, font_changes);
  2166.     }
  2167.     else {
  2168.         ((XFE_EditorView*)m_htmlViewAlias)->
  2169.             getMessageBody(pBody, body_size, font_changes);
  2170.     }
  2171. }
  2172.  
  2173. void
  2174. XFE_ComposeView::doneWithMessageBody(char *pBody)
  2175. {
  2176.     if (m_plaintextP) {
  2177.         ((XFE_TextEditorView *)m_textViewAlias)->doneWithMessageBody(pBody);
  2178.     }
  2179.     else {
  2180.         ((XFE_EditorView *)m_htmlViewAlias)->doneWithMessageBody(pBody);
  2181.     }
  2182. }
  2183.  
  2184. void
  2185. XFE_ComposeView::setComposeWrapState(XP_Bool wrap_p)
  2186. {
  2187.     if (m_plaintextP) {
  2188.         if ( m_textViewAlias )
  2189.             ((XFE_TextEditorView*)m_textViewAlias)->setComposeWrapState(wrap_p);
  2190.     }
  2191.     else {
  2192.         // punt on this one for now... [ XFE_EditorView ]
  2193.     }
  2194. }
  2195.  
  2196. XP_Bool
  2197. XFE_ComposeView::isDelayedSent()
  2198. {
  2199.   return m_delayedSent;
  2200. }
  2201.  
  2202. XP_Bool
  2203. XFE_ComposeView::isHTML()
  2204. {
  2205.   return !m_plaintextP;
  2206. }
  2207.  
  2208.  
  2209. extern "C" void 
  2210. fe_InsertMessageCompositionText(
  2211.         MWContext *context,
  2212.                 const char* text, XP_Bool leaveCursorBeginning)
  2213. {
  2214.  
  2215.   XFE_Frame *f = ViewGlue_getFrame(context);
  2216.  
  2217.   XP_ASSERT(f!=NULL && f->getType() == FRAME_MAILNEWS_COMPOSE);
  2218.  
  2219. #ifdef DEBUG_rhess
  2220.   fprintf(stderr, "fe_InsertMessageCompositionText::[ ]\n");
  2221. #endif  
  2222.  
  2223.   ((XFE_ComposeView*)f->getView())->insertMessageCompositionText(
  2224.                          text, leaveCursorBeginning);
  2225. }
  2226.  
  2227. extern "C" void 
  2228. fe_getMessageBody(
  2229.         MWContext *context,
  2230.         char **pBody, uint32 *body_size, 
  2231.         MSG_FontCode **font_changes)
  2232. {
  2233.  
  2234.   XFE_Frame *f = ViewGlue_getFrame(context);
  2235.  
  2236.   XP_ASSERT(f!=NULL && f->getType() == FRAME_MAILNEWS_COMPOSE);
  2237.  
  2238. #ifdef DEBUG_rhess
  2239.   fprintf(stderr, "fe_getMessageBody::[ ]\n");
  2240. #endif  
  2241.  
  2242.   ((XFE_ComposeView*)f->getView())->getMessageBody(pBody, body_size,
  2243.         font_changes);
  2244. }
  2245. extern "C" void 
  2246. fe_doneWithMessageBody(MWContext *context, char *pBody, uint32 /*body_size*/)
  2247. {
  2248.  
  2249.   XFE_Frame *f = ViewGlue_getFrame(context);
  2250.  
  2251.   XP_ASSERT(f!=NULL && f->getType() == FRAME_MAILNEWS_COMPOSE);
  2252.  
  2253. #ifdef DEBUG_rhess
  2254.   fprintf(stderr, "fe_doneWithMessageBody::[ ]\n");
  2255. #endif  
  2256.  
  2257.   ((XFE_ComposeView*)f->getView())->doneWithMessageBody(pBody);
  2258. }
  2259.  
  2260. extern "C" void
  2261. fe_addToContextList(MWContext *context)
  2262. {
  2263.   struct fe_MWContext_cons *cons; 
  2264.  
  2265.   if ( context== NULL) return;
  2266.  
  2267.   cons =  XP_NEW_ZAP(struct fe_MWContext_cons);
  2268.  
  2269.   if ( cons == NULL ) return;
  2270.  
  2271.   cons->context = context;
  2272.   cons->next = fe_all_MWContexts;
  2273.   fe_all_MWContexts = cons;
  2274.   XP_AddContextToList (context);
  2275. }
  2276.  
  2277. extern "C" void
  2278. fe_set_compose_wrap_state(MWContext *context, XP_Bool wrap_p)
  2279. {
  2280.   XFE_Frame *frame = ViewGlue_getFrame(XP_GetNonGridContext(context));
  2281.  
  2282.   XP_ASSERT(frame->getType() == FRAME_MAILNEWS_COMPOSE);
  2283.  
  2284.   ((XFE_ComposeView*)frame->getView())->setComposeWrapState(wrap_p);
  2285. }
  2286.  
  2287. void
  2288. XFE_ComposeView::subjectUpdate(Widget w, XtPointer)
  2289. {
  2290.   MSG_HEADER_SET msgtype = MSG_SUBJECT_HEADER_MASK;
  2291.   char* value = 0;
  2292.   char *newvalue = 0;
  2293.   MSG_Pane *comppane = (MSG_Pane*)getPane(); 
  2294.  
  2295.   value = fe_GetTextField(w);
  2296.   newvalue = MSG_UpdateHeaderContents(comppane, msgtype, value);
  2297.   if (newvalue) {
  2298.     fe_SetTextField(w, newvalue);
  2299.     MSG_SetCompHeader(comppane, msgtype, newvalue);
  2300.     XP_FREE(newvalue);
  2301.   }
  2302. }
  2303.  
  2304. void
  2305. XFE_ComposeView::subjectChange(Widget w, XtPointer)
  2306. {
  2307.   MSG_HEADER_SET msgtype = MSG_SUBJECT_HEADER_MASK;
  2308.   char* value = 0;
  2309.   MSG_Pane *comppane = (MSG_Pane*)getPane(); 
  2310.  
  2311.   value = fe_GetTextField(w);
  2312.   MSG_SetCompHeader (comppane, msgtype, value);
  2313. }
  2314.  
  2315.  
  2316. void
  2317. XFE_ComposeView::subjectChangeCallback(Widget w, XtPointer clientData, XtPointer callData)
  2318. {
  2319.   XFE_ComposeView *obj = (XFE_ComposeView*)clientData;
  2320.  
  2321.   obj->subjectChange(w, callData);
  2322. }
  2323.  
  2324. void
  2325. XFE_ComposeView::textEditorFocus(Widget who)
  2326. {
  2327. #ifdef DEBUG_rhess2
  2328.     fprintf(stderr, "textEditor::[ %p ]\n", who);
  2329. #endif
  2330.     m_focusW    = who;
  2331. }
  2332.  
  2333. void
  2334. XFE_ComposeView::addressTextFocus(Widget who)
  2335. {
  2336.     unGrabEditor();
  2337.  
  2338. #ifdef DEBUG_rhess2
  2339.     fprintf(stderr, "addressText::[ %p ]\n", who);
  2340. #endif
  2341.     m_addrTextW = who;
  2342.     m_focusW    = who;
  2343. }
  2344.  
  2345. void
  2346. XFE_ComposeView::addressTypeFocus(Widget who)
  2347. {
  2348.     unGrabEditor();
  2349.  
  2350. #ifdef DEBUG_rhess2
  2351.     fprintf(stderr, "addressType::[ %p ]\n", who);
  2352. #endif
  2353.     m_addrTypeW = who;
  2354.     m_focusW    = who;
  2355. }
  2356.  
  2357. void
  2358. XFE_ComposeView::subjectFocus()
  2359. {
  2360.     unGrabEditor();
  2361.  
  2362.     m_focusW = m_subjectW;
  2363. }
  2364.  
  2365. void
  2366. XFE_ComposeView::quoteText(char * value)
  2367. {
  2368.     if (value) {
  2369.         MSG_PastePlaintextQuotation(getPane(), value);
  2370.     }
  2371. }
  2372.  
  2373. void
  2374. XFE_ComposeView::quotePrimarySel_cb(Widget, XtPointer cdata, 
  2375.                                     Atom*, Atom *type, XtPointer value, 
  2376.                                     unsigned long*, int*)
  2377. {
  2378.     XFE_ComposeView *obj = (XFE_ComposeView*)cdata;
  2379.  
  2380.     if (value) {
  2381.         if (*type == XFE_TEXT_ATOM) {
  2382. #ifdef DEBUG_rhess
  2383.             fprintf(stderr, "quotePrimarySel_cb::[ text ]\n");
  2384. #endif
  2385.             obj->quoteText( (char *) value );
  2386.         }
  2387.         else {
  2388. #ifdef DEBUG_rhess
  2389.             fprintf(stderr, "WARNING... [ unknown type atom ]\n");
  2390. #endif
  2391.         }
  2392.     }
  2393. #ifdef DEBUG_rhess
  2394.     else {
  2395.         fprintf(stderr, "quotePrimarySel_cb::[ NULL ]\n");
  2396.     }
  2397. #endif
  2398. }
  2399.  
  2400. void
  2401. XFE_ComposeView::subjectFocusIn_CB(Widget,
  2402.                                    XtPointer clientData,
  2403.                                    XtPointer)
  2404. {
  2405.     XFE_ComposeView *obj = (XFE_ComposeView*)clientData;
  2406.  
  2407.     obj->subjectFocus();
  2408. }
  2409.  
  2410. void
  2411. XFE_ComposeView::expandCallback(Widget, XtPointer clientData, XtPointer)
  2412. {
  2413.   XFE_ComposeView *obj = (XFE_ComposeView*)clientData;
  2414.  
  2415.   obj->toggleAddressArea();
  2416. }
  2417.  
  2418.  
  2419. void
  2420. XFE_ComposeView::toggleAddressArea()
  2421. {
  2422.     Widget widget = m_expand_arrowW;
  2423.  
  2424.     if (m_expanded)
  2425.     { // Current, it is expanded. we need to collapse it
  2426.       XtVaSetValues(widget, XmNarrowDirection, XmARROW_DOWN, 0);
  2427.       m_folderViewAlias->hide();
  2428.       m_expanded = False;
  2429.     }
  2430.     else  // Expand it
  2431.     {
  2432.       XtVaSetValues(widget, XmNarrowDirection, XmARROW_UP, 0);
  2433.       m_folderViewAlias->show();
  2434.       m_expanded = True;
  2435.     }
  2436. }
  2437.  
  2438.  
  2439. XFE_CALLBACK_DEFN(XFE_ComposeView, tabToSubject)(XFE_NotificationCenter*, void*, void*)
  2440. {
  2441.    XDEBUG(printf("About to tab to subject...\n");)
  2442.    unGrabEditor();
  2443. }
  2444.  
  2445. XFE_CALLBACK_DEFN(XFE_ComposeView, textEditorFocusIn)(XFE_NotificationCenter*, void*, void* calldata)
  2446. {
  2447.     Widget who = (Widget) calldata;
  2448.  
  2449.     textEditorFocus(who);
  2450. }
  2451.  
  2452. XFE_CALLBACK_DEFN(XFE_ComposeView, addressTextFocusIn)(XFE_NotificationCenter*, void*, void* calldata)
  2453. {
  2454.     Widget who = (Widget) calldata;
  2455.  
  2456.     addressTextFocus(who);
  2457. }
  2458.  
  2459. XFE_CALLBACK_DEFN(XFE_ComposeView, addressTypeFocusIn)(XFE_NotificationCenter*, void*, void* calldata)
  2460. {
  2461.     Widget who = (Widget) calldata;
  2462.  
  2463.     addressTypeFocus(who);
  2464. }
  2465.  
  2466. void 
  2467. XFE_ComposeView::unGrabEditorProc(Widget, XtPointer cd, XEvent*, Boolean*)
  2468. {
  2469.     XFE_ComposeView *obj = (XFE_ComposeView*)cd;
  2470.  
  2471.     obj->unGrabEditor();
  2472. }
  2473.  
  2474. void
  2475. XFE_ComposeView::unGrabEditor()
  2476. {
  2477.     if (m_editorFocusP) {
  2478. #ifdef DEBUG_rhess
  2479.         fprintf(stderr, "::[ unGrabEditor ]\n");
  2480. #endif
  2481.         focusOut();
  2482.     }
  2483. }
  2484.  
  2485. void
  2486. XFE_ComposeView::editorFocus(Boolean flag)
  2487. {
  2488.   m_editorFocusP = flag;
  2489. }
  2490.  
  2491. Boolean
  2492. XFE_ComposeView::isModified()
  2493. {
  2494.   Boolean modified = False;
  2495.  
  2496.   if ( m_plaintextP )
  2497.    modified = ((XFE_TextEditorView*)m_textViewAlias)->isModified();
  2498.   else 
  2499.    modified = ((XFE_EditorView*)m_htmlViewAlias)->isModified();
  2500.   return modified;
  2501. }
  2502.  
  2503. void
  2504. XFE_ComposeView::updateHeaderInfo(void)
  2505. {
  2506.  
  2507.  
  2508.   ((XFE_ComposeFolderView*)m_folderViewAlias)->updateHeaderInfo();
  2509.   if (m_subjectW)
  2510.   {
  2511.     char *string;
  2512.  
  2513.     string = fe_GetTextField(m_subjectW);
  2514.  
  2515.     MSG_SetCompHeader(getPane(),MSG_SUBJECT_HEADER_MASK,string);
  2516.     XtFree(string);
  2517.   }
  2518.  
  2519. }
  2520.  
  2521. XFE_View*
  2522. XFE_ComposeView::getCommandView(XFE_Command* )
  2523. {
  2524.     //
  2525.     //    We can do a much simpler (and faster) implimentation that
  2526.     //    the XFE_View version, because the only sub view that ever
  2527.     //    impliments XFE_Commands is the html editor view.
  2528.     //
  2529.     if (!m_plaintextP)
  2530.         return (XFE_TextEditorView*)m_htmlViewAlias;
  2531.     else
  2532.         return NULL;
  2533. }
  2534.  
  2535. extern "C" void
  2536. FE_SecurityOptionsChanged(MWContext * pContext)
  2537. {
  2538.    XFE_Frame * pFrame = ViewGlue_getFrame(XP_GetNonGridContext(pContext));
  2539.    if ( pFrame ) {
  2540.         ((XFE_ComposeView*)pFrame->getView())->getToplevel()->
  2541.         notifyInterested(XFE_ComposeView::updateSecurityOption, NULL);
  2542.    }
  2543. }
  2544.  
  2545.