home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / xfe / src / EditorView.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  85.7 KB  |  3,181 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.    EditorView.cpp -- class definition for the editor view class
  20.    Created: Richard Hess <rhess@netscape.com>, 11-Nov-96
  21.  */
  22.  
  23.  
  24. #include "EditorFrame.h"
  25. #include "EditorView.h"
  26. #include "SpellHandler.h"
  27.  
  28. #include <Xm/Label.h>
  29. #include <Xfe/Xfe.h>
  30.  
  31. #include "xpgetstr.h"
  32. #include "fe_proto.h"
  33. #include "edt.h"
  34. #include "xeditor.h"
  35. #ifndef NO_SECURITY
  36. #include "pk11func.h"
  37. #endif
  38.  
  39. #define FE_SYNTAX_ERROR() doSyntaxErrorAlert(view, info)
  40.  
  41. //
  42. //    This acts as an encapsulator for the doCommand() method.
  43. //    Sub-classes impliment a reallyDoCommand(), and leave the
  44. //    boring maintainence work to this class. This approach
  45. //    saves every sub-class from calling super::doCommand(),
  46. //    which would really be a drag, now wouldn't it.
  47. //
  48. class XFE_EditorViewCommand : public XFE_ViewCommand
  49. {
  50. public:
  51.     XFE_EditorViewCommand(char* name) : XFE_ViewCommand(name) {};
  52.     
  53.     virtual void    reallyDoCommand(XFE_View*, XFE_CommandInfo*) = 0;
  54.     virtual XP_Bool requiresChromeUpdate() {
  55.         return TRUE;
  56.     };
  57.     void            doCommand(XFE_View* v_view, XFE_CommandInfo* info) {
  58.         XFE_EditorView* view = (XFE_EditorView*)v_view;
  59.         reallyDoCommand(view, info);
  60.         if (requiresChromeUpdate()) {
  61.             view->updateChrome();
  62.         }
  63.     }; 
  64. };
  65.  
  66. class UndoCommand : public XFE_EditorViewCommand
  67. {
  68. public:
  69.     UndoCommand() : XFE_EditorViewCommand(xfeCmdUndo) {};
  70.  
  71.     XP_Bool isEnabled(XFE_View* view, XFE_CommandInfo*) {
  72.         return fe_EditorCanUndo(view->getContext(), NULL);
  73.     };
  74.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  75.         fe_EditorUndo(view->getContext());
  76.     }; 
  77.     char*   getLabel(XFE_View* view, XFE_CommandInfo*) {
  78. #if EDITOR_UNDO
  79.         char* label;
  80.         fe_EditorCanUndo(view->getContext(), (unsigned char **)&label);
  81.         return label;
  82. #else
  83.         //
  84.         //    Well, in the new world order none of the stuff that I
  85.         //    used to use for Undo works any more, so until we fix it...
  86.         //
  87.         Widget top = view->getToplevel()->getBaseWidget();
  88.         return XfeSubResourceGetStringValue(top,
  89.                                             "undo", 
  90.                                             "UndoItem",
  91.                                             XmNlabelString, 
  92.                                             XmCLabelString,
  93.                                             NULL);
  94. #endif
  95.     };
  96. };
  97.  
  98. class RedoCommand : public XFE_EditorViewCommand
  99. {
  100. public:
  101.     RedoCommand() : XFE_EditorViewCommand(xfeCmdRedo) {};
  102.     
  103.     XP_Bool isEnabled(XFE_View* view, XFE_CommandInfo*) {
  104.         return fe_EditorCanRedo(view->getContext(), NULL);
  105.     };
  106.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  107.         fe_EditorRedo(view->getContext());
  108.     }; 
  109.     char*   getLabel(XFE_View* view, XFE_CommandInfo*) {
  110. #if EDITOR_UNDO
  111.         char* label;
  112.         fe_EditorCanRedo(view->getContext(), (unsigned char **)&label);
  113.         return label;
  114. #else
  115.         //    See above.
  116.         Widget top = view->getToplevel()->getBaseWidget();
  117.         return XfeSubResourceGetStringValue(top,
  118.                                             "redo", 
  119.                                             "UndoItem",
  120.                                             XmNlabelString, 
  121.                                             XmCLabelString,
  122.                                             NULL);
  123. #endif
  124.     };
  125. };
  126.  
  127. class CutCommand : public XFE_EditorViewCommand
  128. {
  129. public:
  130.     CutCommand() : XFE_EditorViewCommand(xfeCmdCut) {};
  131.  
  132.     XP_Bool isEnabled(XFE_View* view, XFE_CommandInfo*) {
  133.         return fe_EditorCanCut(view->getContext());
  134.     };
  135.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo* info) {
  136.         fe_EditorCut(view->getContext(), fe_GetTimeFromEvent(info->event));
  137.     }; 
  138. };
  139.  
  140. class CopyCommand : public XFE_EditorViewCommand
  141. {
  142. public:
  143.     CopyCommand() : XFE_EditorViewCommand(xfeCmdCopy) {};
  144.  
  145.     XP_Bool isEnabled(XFE_View* view, XFE_CommandInfo*) {
  146.         return fe_EditorCanCopy(view->getContext());
  147.     };
  148.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo* calldata); 
  149. };
  150.  
  151. void CopyCommand::reallyDoCommand(XFE_View* view, XFE_CommandInfo* info) {
  152.     fe_EditorCopy(view->getContext(), fe_GetTimeFromEvent(info->event));
  153. }; 
  154.  
  155. class PasteCommand : public XFE_EditorViewCommand
  156. {
  157. public:
  158.     PasteCommand() : XFE_EditorViewCommand(xfeCmdPaste) {};
  159.  
  160.     XP_Bool isEnabled(XFE_View* view, XFE_CommandInfo* info) {
  161.         XP_Bool rv = FALSE;
  162.  
  163.         if (info != NULL && *info->nparams > 0) {
  164.             if (XP_STRCASECMP(info->params[0], "clipboard") == 0) {
  165.                 rv = fe_EditorCanPaste(view->getContext());
  166.             } else if (XP_STRCASECMP(info->params[0], "selection") == 0) {
  167.                 rv = TRUE; // lazy, but this would be a real performance hit
  168.             } else {
  169.                 FE_SYNTAX_ERROR();
  170.             }
  171.         } else {
  172.             rv = fe_EditorCanPaste(view->getContext());
  173.         }
  174.         return rv;
  175.     };
  176.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo* info) {
  177.         Boolean from_selection = FALSE;
  178.         MWContext* context = view->getContext();
  179.  
  180.         if (info != NULL) {
  181.  
  182.             Time now = fe_GetTimeFromEvent(info->event);
  183.  
  184.             if (*info->nparams > 0) {
  185.                 if (XP_STRCASECMP(info->params[0], "clipboard") == 0) {
  186.                     from_selection = FALSE;
  187.                 } else if (XP_STRCASECMP(info->params[0], "selection") == 0) {
  188.                     from_selection = TRUE;
  189.                 } else {
  190.                     FE_SYNTAX_ERROR();
  191.                 }
  192.             }
  193.  
  194.             if (from_selection) {
  195.                 // NOTE... [ if it's triggered off a mouse click (Btn2), 
  196.                 //         [ set the location before you paste...
  197.                 //
  198.                 if ((info->event != NULL) &&
  199.                     (info->event->type == ButtonPress)) {
  200.                     fe_EditorGrabFocus(context, info->event);
  201.                 }
  202.                 fe_EditorPastePrimarySel(context, now);
  203.             }
  204.             else
  205.                 fe_EditorPaste(context, now);
  206.         }
  207.     }; 
  208. };
  209.  
  210. class AlwaysEnabledCommand : public XFE_EditorViewCommand
  211. {
  212. public:
  213.     AlwaysEnabledCommand(char* name) : XFE_EditorViewCommand(name) {};
  214.  
  215.     XP_Bool isEnabled(XFE_View*, XFE_CommandInfo*) {
  216.         return True;
  217.     };
  218. };
  219.  
  220. class DeleteCommand : public AlwaysEnabledCommand
  221. {
  222. public:
  223.     DeleteCommand() : AlwaysEnabledCommand(xfeCmdDeleteItem) {};
  224.  
  225.     virtual XP_Bool isSlow() {
  226.         return FALSE;
  227.     };
  228.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo* info) {
  229.         Boolean previous = FALSE;
  230.         if (info != NULL && *info->nparams > 0) {
  231.             char* param = info->params[0];
  232.  
  233.             if (XP_STRCASECMP(param, "next") == 0)
  234.                 previous = FALSE;
  235.             else if (XP_STRCASECMP(param, "previous") == 0)
  236.                 previous = TRUE;
  237.             else if (XP_STRCASECMP(param, "endOfLine") == 0) {
  238.                 EDT_EndOfLine(view->getContext(), True);
  239.             }
  240.             else {
  241.                 FE_SYNTAX_ERROR();
  242.             }
  243.         }
  244.  
  245.         fe_EditorDeleteItem(view->getContext(), previous);
  246.     }; 
  247. };
  248.  
  249. class SpellCommand : public XFE_EditorViewCommand
  250. {
  251. public:
  252.     SpellCommand() : XFE_EditorViewCommand(xfeCmdSpellCheck) {};
  253.  
  254.     XP_Bool isDynamic() { return TRUE; };
  255.  
  256.     XP_Bool isEnabled(XFE_View* view, XFE_CommandInfo*) {
  257.         return xfe_SpellCheckerAvailable(view->getContext());
  258.     };
  259.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  260.         xfe_EditorSpellCheck(view->getContext());
  261.     }; 
  262. };
  263.  
  264. class SaveCommand : public AlwaysEnabledCommand
  265. {
  266. public:
  267.     SaveCommand() : AlwaysEnabledCommand(xfeCmdSave) {};
  268.  
  269.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  270.         fe_EditorSave(view->getContext());
  271.     }; 
  272. };
  273.  
  274. class SaveAsCommand : public AlwaysEnabledCommand
  275. {
  276. public:
  277.     SaveAsCommand() : AlwaysEnabledCommand(xfeCmdSaveAs) {};
  278.  
  279.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  280.         fe_EditorSaveAs(view->getContext());
  281.     }; 
  282. };
  283.  
  284. class PublishCommand : public AlwaysEnabledCommand
  285. {
  286. public:
  287.     PublishCommand() : AlwaysEnabledCommand(xfeCmdPublish) {};
  288.  
  289.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  290.         fe_EditorPublish(view->getContext());
  291.     }; 
  292. };
  293.  
  294. class DeleteTableCommand : public XFE_EditorViewCommand
  295. {
  296. public:
  297.     DeleteTableCommand() : XFE_EditorViewCommand(xfeCmdDeleteTable) {};
  298.  
  299.     XP_Bool isEnabled(XFE_View* view, XFE_CommandInfo*) {
  300.         return fe_EditorTableCanDelete(view->getContext());
  301.     };
  302.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  303.         fe_EditorTableDelete(view->getContext());
  304.     }; 
  305. };
  306.  
  307. class DeleteTableCellCommand : public XFE_EditorViewCommand
  308. {
  309. public:
  310.     DeleteTableCellCommand() : XFE_EditorViewCommand(xfeCmdDeleteTableCell) {};
  311.  
  312.     XP_Bool isEnabled(XFE_View* view, XFE_CommandInfo*) {
  313.         return fe_EditorTableCellCanDelete(view->getContext());
  314.     };
  315.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  316.         fe_EditorTableCellDelete(view->getContext());
  317.     }; 
  318. };
  319.  
  320. class DeleteTableRowCommand : public XFE_EditorViewCommand
  321. {
  322. public:
  323.     DeleteTableRowCommand() : XFE_EditorViewCommand(xfeCmdDeleteTableRow) {};
  324.  
  325.     XP_Bool isEnabled(XFE_View* view, XFE_CommandInfo*) {
  326.         return fe_EditorTableRowCanDelete(view->getContext());
  327.     };
  328.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  329.         fe_EditorTableRowDelete(view->getContext());
  330.     }; 
  331. };
  332.  
  333. class DeleteTableColumnCommand : public XFE_EditorViewCommand
  334. {
  335. public:
  336.     DeleteTableColumnCommand() : XFE_EditorViewCommand(xfeCmdDeleteTableColumn) {};
  337.  
  338.     XP_Bool isEnabled(XFE_View* view, XFE_CommandInfo*) {
  339.         return fe_EditorTableColumnCanDelete(view->getContext());
  340.     };
  341.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  342.         fe_EditorTableColumnDelete(view->getContext());
  343.     }; 
  344. };
  345.  
  346. class RemoveLinkCommand : public XFE_EditorViewCommand
  347. {
  348. public:
  349.     RemoveLinkCommand() : XFE_EditorViewCommand(xfeCmdRemoveLink) {};
  350.  
  351.     XP_Bool isEnabled(XFE_View* view, XFE_CommandInfo*) {
  352.         return fe_EditorCanRemoveLinks(view->getContext());
  353.     };
  354.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  355.         fe_EditorRemoveLinks(view->getContext());
  356.     }; 
  357. };
  358.  
  359. class SelectAllCommand : public AlwaysEnabledCommand
  360. {
  361. public:
  362.     SelectAllCommand() : AlwaysEnabledCommand(xfeCmdSelectAll) {};
  363.  
  364.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  365.         fe_EditorSelectAll(view->getContext());
  366.     }; 
  367. };
  368.  
  369. class FindCommand : public AlwaysEnabledCommand
  370. {
  371. public:
  372.     FindCommand() : AlwaysEnabledCommand(xfeCmdFindInObject) {};
  373.  
  374.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  375.         fe_EditorFind(view->getContext());
  376.     }; 
  377. };
  378.  
  379. class FindAgainCommand : public XFE_EditorViewCommand
  380. {
  381. public:
  382.     FindAgainCommand() : XFE_EditorViewCommand(xfeCmdFindAgain) {};
  383.  
  384.     XP_Bool isEnabled(XFE_View* view, XFE_CommandInfo*) {
  385.         return fe_EditorCanFindAgain(view->getContext());
  386.     };
  387.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  388.         fe_EditorFindAgain(view->getContext());
  389.     }; 
  390. };
  391.  
  392. static char*
  393. get_show_hide_label(Widget widget, char* root, Boolean show)
  394. {
  395.     char* prefix;
  396.     char  name[256];
  397.     
  398.     if (show)
  399.         prefix = "show";
  400.     else
  401.         prefix = "hide";
  402.  
  403.     XP_STRCPY(name, prefix);
  404.     if (root != NULL)
  405.         XP_STRCAT(name, root);
  406.  
  407.     return XfeSubResourceGetStringValue(widget,
  408.                                         name, 
  409.                                         XfeClassNameForWidget(widget),
  410.                                         XmNlabelString, 
  411.                                         XmCLabelString,
  412.                                         NULL);
  413. }
  414.  
  415. class ToggleParagraphMarksCommand : public AlwaysEnabledCommand
  416. {
  417. public:
  418.     ToggleParagraphMarksCommand() :
  419.         AlwaysEnabledCommand(xfeCmdToggleParagraphMarks) {};
  420.  
  421.     XP_Bool isSelected(XFE_View* view, XFE_CommandInfo*) {
  422.         return fe_EditorParagraphMarksGetState(view->getContext());
  423.     };
  424.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  425.         MWContext* context = view->getContext();
  426.         Boolean    set = fe_EditorParagraphMarksGetState(context);
  427.         fe_EditorParagraphMarksSetState(context, !set);
  428.     }; 
  429.     char*   getLabel(XFE_View* view, XFE_CommandInfo* info) {
  430.  
  431.         char* string = NULL;
  432.  
  433.         if (info != NULL) {
  434.             MWContext* context = view->getContext();
  435.             Boolean    set = fe_EditorParagraphMarksGetState(context);
  436.  
  437.             string = get_show_hide_label(info->widget, "ParagraphMarks", !set);
  438.         }
  439.         return string;
  440.     };
  441. };
  442.  
  443. class ToggleTableBordersCommand : public AlwaysEnabledCommand
  444. {
  445. public:
  446.     ToggleTableBordersCommand() :
  447.         AlwaysEnabledCommand(xfeCmdToggleTableBorders) {};
  448.  
  449.     XP_Bool isSelected(XFE_View* view, XFE_CommandInfo*) {
  450.         return fe_EditorDisplayTablesGet(view->getContext());
  451.     };
  452.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  453.         MWContext* context = view->getContext();
  454.         Boolean    set = fe_EditorDisplayTablesGet(context);
  455.         fe_EditorDisplayTablesSet(context, !set);
  456.     }; 
  457. };
  458.  
  459. class ReloadCommand : public AlwaysEnabledCommand
  460. {
  461. public:
  462.     ReloadCommand() : AlwaysEnabledCommand(xfeCmdReload) {};
  463.  
  464.     XP_Bool isEnabled(XFE_View* view, XFE_CommandInfo*) {
  465.         return  !EDT_IS_NEW_DOCUMENT(view->getContext());
  466.     };
  467.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo* info) {
  468.  
  469.         Boolean do_super = (info != NULL &&
  470.                             *info->nparams > 0 &&
  471.                             XP_STRCASECMP(info->params[0], "super") == 0);
  472.         fe_EditorReload(view->getContext(), do_super);
  473.     }; 
  474. };
  475.  
  476. class RefreshCommand : public AlwaysEnabledCommand
  477. {
  478. public:
  479.     RefreshCommand() : AlwaysEnabledCommand(xfeCmdRefresh) {};
  480.  
  481.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  482.         fe_EditorRefresh(view->getContext());
  483.     }; 
  484. };
  485.  
  486. class InsertLinkCommand : public AlwaysEnabledCommand
  487. {
  488. public:
  489.     InsertLinkCommand() : AlwaysEnabledCommand(xfeCmdInsertLink) {};
  490.  
  491.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  492.         fe_EditorInsertLinkDialogDo(view->getContext());
  493.     }; 
  494. };
  495.  
  496. class InsertTargetCommand : public AlwaysEnabledCommand
  497. {
  498. public:
  499.     InsertTargetCommand() : AlwaysEnabledCommand(xfeCmdInsertTarget) {};
  500.  
  501.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  502.         fe_EditorTargetPropertiesDialogDo(view->getContext());
  503.     }; 
  504. };
  505.  
  506. class InsertImageCommand : public AlwaysEnabledCommand
  507. {
  508. public:
  509.     InsertImageCommand() : AlwaysEnabledCommand(xfeCmdInsertImage) {};
  510.  
  511.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  512.         fe_EditorPropertiesDialogDo(view->getContext(),
  513.                                     XFE_EDITOR_PROPERTIES_IMAGE_INSERT);
  514.     }; 
  515. };
  516.  
  517. class InsertBulletedListCommand : public AlwaysEnabledCommand
  518. {
  519. public:
  520.     InsertBulletedListCommand() : 
  521.         AlwaysEnabledCommand(xfeCmdInsertBulletedList) {};
  522.  
  523.     XP_Bool isDynamic() { return TRUE; };
  524.  
  525.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  526.         fe_EditorToggleList(view->getContext(), P_UNUM_LIST);
  527.     }; 
  528.     XP_Bool isSelected(XFE_View* view, XFE_CommandInfo*) {
  529.         return EDT_GetToggleListState(view->getContext(), P_UNUM_LIST);
  530.     };
  531. };
  532.  
  533. class InsertNumberedListCommand : public AlwaysEnabledCommand
  534. {
  535. public:
  536.     InsertNumberedListCommand() : 
  537.         AlwaysEnabledCommand(xfeCmdInsertNumberedList) {};
  538.  
  539.     XP_Bool isDynamic() { return TRUE; };
  540.  
  541.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  542.         fe_EditorToggleList(view->getContext(), P_NUM_LIST);
  543.     }; 
  544.     XP_Bool isSelected(XFE_View* view, XFE_CommandInfo*) {
  545.         return EDT_GetToggleListState(view->getContext(), P_NUM_LIST);
  546.     };
  547. };
  548.  
  549. class InsertHorizontalLineCommand : public AlwaysEnabledCommand
  550. {
  551. public:
  552.     InsertHorizontalLineCommand() : 
  553.         AlwaysEnabledCommand(xfeCmdInsertHorizontalLine) {};
  554.  
  555.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo* info) {
  556.  
  557.         MWContext* context = view->getContext();
  558.  
  559.         if (info != NULL && 
  560.             *info->nparams > 0 &&
  561.             XP_STRCASECMP(info->params[0], "dialog")) {
  562.             fe_EditorHorizontalRulePropertiesDialogDo(view->getContext());
  563.         } else {
  564.             fe_EditorInsertHorizontalRule(context);
  565.         }
  566.     }; 
  567. };
  568.  
  569. class InsertTableCommand : public XFE_EditorViewCommand
  570. {
  571. public:
  572.     InsertTableCommand() : XFE_EditorViewCommand(xfeCmdInsertTable) {};
  573.  
  574.     XP_Bool isEnabled(XFE_View* view, XFE_CommandInfo*) {
  575.         return fe_EditorTableCanInsert(view->getContext());
  576.     };
  577.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  578.         fe_EditorTableCreateDialogDo(view->getContext());
  579.     }; 
  580. };
  581.  
  582. class InsertTableRowCommand : public XFE_EditorViewCommand
  583. {
  584. public:
  585.     InsertTableRowCommand() : XFE_EditorViewCommand(xfeCmdInsertTableRow) {};
  586.  
  587.     XP_Bool isEnabled(XFE_View* view, XFE_CommandInfo*) {
  588.         return fe_EditorTableRowCanInsert(view->getContext());
  589.     };
  590.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  591.         fe_EditorTableRowInsert(view->getContext(), NULL);
  592.     }; 
  593. };
  594.  
  595. class InsertTableColumnCommand : public XFE_EditorViewCommand
  596. {
  597. public:
  598.     InsertTableColumnCommand() : XFE_EditorViewCommand(xfeCmdInsertTableColumn) {};
  599.  
  600.     XP_Bool isEnabled(XFE_View* view, XFE_CommandInfo*) {
  601.         return fe_EditorTableColumnCanInsert(view->getContext());
  602.     };
  603.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  604.         fe_EditorTableColumnInsert(view->getContext(), NULL);
  605.     }; 
  606. };
  607.  
  608. class InsertTableCellCommand : public XFE_EditorViewCommand
  609. {
  610. public:
  611.     InsertTableCellCommand() : XFE_EditorViewCommand(xfeCmdInsertTableCell) {};
  612.  
  613.     XP_Bool isEnabled(XFE_View* view, XFE_CommandInfo*) {
  614.         return fe_EditorTableCellCanInsert(view->getContext());
  615.     };
  616.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  617.         fe_EditorTableCellInsert(view->getContext(), NULL);
  618.     }; 
  619. };
  620.  
  621. class InsertHtmlCommand : public AlwaysEnabledCommand
  622. {
  623. public:
  624.     InsertHtmlCommand() : AlwaysEnabledCommand(xfeCmdInsertHtml) {};
  625.  
  626.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  627.         fe_EditorHtmlPropertiesDialogDo(view->getContext());
  628.     }; 
  629. };
  630.  
  631. class InsertBreakBelowImageCommand : public AlwaysEnabledCommand
  632. {
  633. public:
  634.     InsertBreakBelowImageCommand() :
  635.         AlwaysEnabledCommand(xfeCmdInsertBreakBelowImage) {};
  636.  
  637.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  638.  
  639.         fe_EditorLineBreak(view->getContext(), ED_BREAK_BOTH);
  640.  
  641.     }; 
  642. };
  643.  
  644. class InsertNonBreakingSpaceCommand : public AlwaysEnabledCommand
  645. {
  646. public:
  647.     InsertNonBreakingSpaceCommand() :
  648.         AlwaysEnabledCommand(xfeCmdInsertNonBreakingSpace) {};
  649.  
  650.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  651.  
  652.         fe_EditorNonBreakingSpace(view->getContext());
  653.     }; 
  654. };
  655.  
  656. struct parse_tokens_st {
  657.     char*    name;
  658.     unsigned bits;
  659. };
  660.  
  661. static unsigned
  662. tokens_cmp(parse_tokens_st* mapping, char* s, unsigned& bits)
  663. {
  664.     char *p;
  665.     char *q;
  666.     int i;
  667.     unsigned nmatches = 0;
  668.     
  669.     bits = 0;
  670.  
  671.     s = strdup(s); /* lazy */
  672.     
  673.     for (p = s; *p; ) {
  674.         q = strchr(p, '|'); /* look for or */
  675.  
  676.         if (q)
  677.             *q++ = '\0'; /* punch out or */
  678.         else
  679.             q = &p[strlen(p)];
  680.         
  681.         /*
  682.          *    Check the token.
  683.          */
  684.         for (i = 0; mapping[i].name != NULL; i++) {
  685.             if (strcmp(p, mapping[i].name) == 0) {
  686.                 bits |= mapping[i].bits;
  687.                 nmatches++;
  688.                 break;
  689.             }
  690.         }
  691.  
  692.         p = q;
  693.     }
  694.     
  695.     /* Use first (default) value for no match */
  696.     if (nmatches == 0)
  697.         bits = mapping[0].bits;
  698.         
  699.     free(s);
  700.     
  701.     return nmatches;
  702. }
  703.  
  704. static parse_tokens_st font_size_tokens[] = {
  705.     { "default", ED_FONTSIZE_ZERO },
  706.     { "-2",      ED_FONTSIZE_MINUS_TWO },
  707.     { "-1",      ED_FONTSIZE_MINUS_ONE },
  708.     {  "0",      ED_FONTSIZE_ZERO },
  709.     { "+0",      ED_FONTSIZE_ZERO },
  710.     { "+1",      ED_FONTSIZE_PLUS_ONE },
  711.     { "+2",      ED_FONTSIZE_PLUS_TWO },
  712.     { "+3",      ED_FONTSIZE_PLUS_THREE },
  713.     { "+4",      ED_FONTSIZE_PLUS_FOUR },
  714.     { NULL }
  715. };
  716.  
  717. static XFE_CommandParameters set_font_size_params[] = {
  718.     { "-2",      (void*)ED_FONTSIZE_MINUS_TWO  },
  719.     { "-1",      (void*)ED_FONTSIZE_MINUS_ONE  },
  720.     { "+0",      (void*)ED_FONTSIZE_ZERO       },
  721.     { "+1",      (void*)ED_FONTSIZE_PLUS_ONE   },
  722.     { "+2",      (void*)ED_FONTSIZE_PLUS_TWO   },
  723.     { "+3",      (void*)ED_FONTSIZE_PLUS_THREE },
  724.     { "+4",      (void*)ED_FONTSIZE_PLUS_FOUR  },
  725.     { NULL }
  726. };
  727.  
  728.  
  729. int
  730. XFE_CommandParametersGetIndexByName(XFE_CommandParameters* list, char* name)
  731. {
  732.     unsigned i;
  733.     for (i = 0; list[i].name != NULL; i++) {
  734.         if (XP_STRCASECMP(name, list[i].name) == 0)
  735.             return i;
  736.     }
  737.     return -1;
  738. }
  739.  
  740. int
  741. XFE_CommandParametersGetIndexByData(XFE_CommandParameters* list, void* data)
  742. {
  743.     unsigned i;
  744.     for (i = 0; list[i].name != NULL; i++) {
  745.         if (data == list[i].data)
  746.             return i;
  747.     }
  748.     return -1;
  749. }
  750.  
  751. static Boolean
  752. style_is_determinate(MWContext* context, ED_TextFormat foo)
  753. {
  754.     EDT_CharacterData* edt_cdata = EDT_GetCharacterData(context);
  755.     Boolean rv = FALSE;
  756.  
  757.     if (edt_cdata != NULL) {
  758.         rv = ((edt_cdata->mask & foo) != 0);
  759.         EDT_FreeCharacterData(edt_cdata);
  760.     }
  761.     
  762.     return rv;
  763. }
  764.  
  765. class SetFontSizeCommand : public AlwaysEnabledCommand
  766. {
  767. public:
  768.     SetFontSizeCommand() : AlwaysEnabledCommand(xfeCmdSetFontSize) {};
  769.     SetFontSizeCommand(char* name) : AlwaysEnabledCommand(name) {};
  770.  
  771.     virtual XP_Bool isDynamic() { return TRUE; };
  772.  
  773.     XP_Bool isDeterminate(XFE_View* view, XFE_CommandInfo*) {
  774.         return style_is_determinate(view->getContext(), TF_FONT_SIZE);
  775.     };
  776.     XP_Bool isSelected(XFE_View* view, ED_FontSize size) {
  777.         return size == fe_EditorFontSizeGet(view->getContext());
  778.     }
  779.     XP_Bool isSelected(XFE_View* view, XFE_CommandInfo* info) {
  780.         int i;
  781.         if (info == NULL || info->params == NULL)
  782.             return FALSE;
  783.  
  784.         for (i = 0; set_font_size_params[i].name != NULL; i++) {
  785.             char*       name = set_font_size_params[i].name;
  786.             ED_FontSize size = (ED_FontSize)set_font_size_params[i].data;
  787.             if (XP_STRCMP(name, info->params[0]) == 0) {
  788.                 return isSelected(view, size);
  789.             }
  790.         }
  791.         return FALSE;
  792.     }
  793.     XFE_CommandParameters* getParameters(XFE_View*) {
  794.         return (XFE_CommandParameters*)set_font_size_params;
  795.     }
  796.     int getParameterIndex(XFE_View* view) {
  797.         MWContext*  context;
  798.         ED_FontSize size;
  799.         unsigned    i;
  800.  
  801.         if (!isDeterminate(view, NULL))
  802.             return -1;
  803.  
  804.         context = view->getContext();
  805.         size = fe_EditorFontSizeGet(context);
  806.  
  807.         if (size == ED_FONTSIZE_DEFAULT)
  808.             return 2;
  809.  
  810.         for (i = 0; set_font_size_params[i].name != NULL; i++) {
  811.             ED_FontSize match = (ED_FontSize)set_font_size_params[i].data;
  812.             if (match == size)
  813.                 return i;
  814.         }
  815.         return -1;
  816.     }
  817.     void    set(XFE_View* view, ED_FontSize size = ED_FONTSIZE_ZERO) {
  818.         fe_EditorFontSizeSet(view->getContext(), size);
  819.     }
  820.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo* calldata) {
  821.         //   FIXME
  822.         XFE_CommandInfo* info = (XFE_CommandInfo*)calldata;
  823.         ED_FontSize size = ED_FONTSIZE_ZERO; //  default
  824.  
  825.         if (info) {
  826.             String* params = info->params;
  827.             Cardinal nparams = *info->nparams;
  828.             unsigned foo;
  829.  
  830.             if (nparams > 0) {
  831.                 MWContext* context = view->getContext();
  832.  
  833.                 if (XP_STRCASECMP(params[0], "increase") == 0) {
  834.                     size = (ED_FontSize)
  835.                         ((unsigned)fe_EditorFontSizeGet(context) + 1);
  836.                 } else if (XP_STRCASECMP(params[0], "decrease") == 0) {
  837.                     size = (ED_FontSize)
  838.                         ((unsigned)fe_EditorFontSizeGet(context) - 1);
  839.                 } else if (tokens_cmp(font_size_tokens, params[0], foo)!=0) {
  840.                     size = (ED_FontSize)foo;
  841.                 } else { /* junk */
  842.                     FE_SYNTAX_ERROR();
  843.                     return;
  844.                 }
  845.             }
  846.  
  847.             set(view, size);
  848.         }
  849.  
  850.     };
  851.     
  852. };
  853.  
  854. class SetFontFaceCommand : public AlwaysEnabledCommand
  855. {
  856. private:
  857.     XFE_CommandParameters* m_params;
  858. public:
  859.     SetFontFaceCommand() : AlwaysEnabledCommand(xfeCmdSetFontFace) {
  860.         m_params = NULL;
  861.     }
  862.     SetFontFaceCommand(char* name) : AlwaysEnabledCommand(name) {
  863.         m_params = NULL;
  864.     }
  865.     virtual XP_Bool isDynamic() { return TRUE; };
  866.     XP_Bool isDeterminate(XFE_View* view, XFE_CommandInfo*) {
  867.         return style_is_determinate(view->getContext(), TF_FONT_FACE);
  868.     };
  869.     XP_Bool isSelected(XFE_View* view, XFE_CommandInfo* info) {
  870.         XP_Bool rv = FALSE;
  871.  
  872.         if (info != NULL && info->params != NULL) {
  873.             
  874.             XFE_CommandParameters* params = getParameters(view);
  875.             int index = XFE_CommandParametersGetIndexByName(params,
  876.                                                             info->params[0]);
  877.  
  878.             if (index == get(view))
  879.                 rv = TRUE;
  880.         }
  881.         return rv;
  882.     }
  883.     char*   getLabel(XFE_View*, XFE_CommandInfo* info) {
  884.         char* label = NULL;
  885.         if (info != NULL && info->params != NULL)
  886.             label = info->params[0];
  887.         return label;
  888.     };
  889.     int get(XFE_View* view) {
  890.         MWContext* context = view->getContext();
  891.         int index = EDT_GetFontFaceIndex(context);
  892.         if (ED_FONT_LOCAL == index) {
  893.             char* name = EDT_GetFontFace(context);
  894.             XFE_CommandParameters* params = getParameters(view);
  895.             index = XFE_CommandParametersGetIndexByName(params, name);
  896.             if (index == -1)
  897.                 index = 0;
  898.         }
  899.         return index;
  900.     }
  901.     void set(XFE_View* view, int index) {
  902.         MWContext* context = view->getContext();
  903.         XFE_CommandParameters* params = getParameters(view);
  904.         char* name = params[index].name;
  905.         EDT_SetFontFace(context, NULL, index, name);
  906.     }
  907.     int getParameterIndex(XFE_View* view) {
  908.         return get(view);
  909.     }
  910.     XFE_CommandParameters* getParameters(XFE_View* view);
  911.     void reallyDoCommand(XFE_View* view, XFE_CommandInfo* info);
  912. };
  913.  
  914. static unsigned
  915. edt_list_count(char* list)
  916. {
  917.     unsigned n;
  918.     char* p;
  919.  
  920.     if (list == NULL)
  921.         return 0;
  922.  
  923.     for (n = 0, p = list; *p != '\0'; p += XP_STRLEN(p) + 1, n++)
  924.         ;
  925.  
  926.     return n;
  927. }
  928.  
  929. static char*
  930. edt_list_next(char* list)
  931. {
  932.     char* p;
  933.  
  934.     if (list == NULL)
  935.         return NULL;
  936.  
  937.     for (p = list; *p != '\0'; p++)
  938.         ;
  939.  
  940.     p++;
  941.  
  942.     if (*p == '\0')
  943.         return NULL;
  944.     else
  945.         return p;
  946. }
  947.  
  948. XFE_CommandParameters*
  949. SetFontFaceCommand::getParameters(XFE_View*)
  950. {
  951.     if (m_params != NULL)
  952.         return m_params;
  953.  
  954.     char* faces = EDT_GetFontFaces();
  955.     if (faces == NULL)
  956.         faces = "";
  957.  
  958.     unsigned n;
  959.     char* p;
  960.     for (n = 0, p = faces; *p != '\0'; p += strlen(p) + 1, n++)
  961.         ;
  962.  
  963.     m_params = (XFE_CommandParameters*)XP_ALLOC(sizeof(XFE_CommandParameters)
  964.                                                 *
  965.                                                 (edt_list_count(faces)+1));
  966.  
  967.     for (p = faces, n = 0; p != NULL; p = edt_list_next(p), n++) {
  968.         m_params[n].name = XP_STRDUP(p); // probably dup.
  969.         m_params[n].data = (void*)n;
  970.     }
  971.     m_params[n].name = NULL;
  972.  
  973.     return m_params;
  974. }
  975.  
  976. void
  977. SetFontFaceCommand::reallyDoCommand(XFE_View* view, XFE_CommandInfo* info)
  978. {
  979.     int index = 0;
  980.  
  981.     if (info != NULL && info->params != NULL) {
  982.         index = XFE_CommandParametersGetIndexByName(getParameters(view),
  983.                                                     info->params[0]);
  984.         if (index == -1) {
  985.             FE_SYNTAX_ERROR();
  986.             return;
  987.         }
  988.     }
  989.     
  990.     set(view, index);
  991. }
  992.  
  993. class SetFontColorCommand : public AlwaysEnabledCommand
  994. {
  995. public:
  996.     SetFontColorCommand() : AlwaysEnabledCommand(xfeCmdSetFontColor) {
  997.         m_params = NULL;
  998.     };
  999.  
  1000.     virtual XP_Bool isDynamic() { return TRUE; };
  1001.     XP_Bool isDeterminate(XFE_View* view, XFE_CommandInfo*) {
  1002.         return style_is_determinate(view->getContext(), TF_FONT_COLOR);
  1003.     };
  1004.     XFE_CommandParameters* getParameters(XFE_View* view);
  1005.     int getParameterIndex(XFE_View* view);
  1006.     void setParameterIndex(XFE_View* view, unsigned index);
  1007.     void reallyDoCommand(XFE_View* view, XFE_CommandInfo* info);
  1008. private:
  1009.     XFE_CommandParameters* m_params;
  1010. };
  1011.  
  1012. XFE_CommandParameters*
  1013. SetFontColorCommand::getParameters(XFE_View*)
  1014. {
  1015.     unsigned n;
  1016.  
  1017.     if (m_params != NULL)
  1018.         return m_params;
  1019.  
  1020.     m_params = (XFE_CommandParameters*)XP_ALLOC(sizeof(XFE_CommandParameters)
  1021.                                                 *
  1022.                                                 (MAX_NS_COLORS+2));
  1023.  
  1024.     m_params[0].name = NULL;
  1025.     m_params[0].data = (void*)0;
  1026.     LO_Color loColor;
  1027.  
  1028.     for (n = 1; n <= MAX_NS_COLORS; n++)
  1029.     {
  1030.         EDT_GetNSColor(n-1, &loColor);
  1031.  
  1032.         m_params[n].name = NULL;
  1033.         m_params[n].data = (void*)RGB_TO_WORD(loColor.red, loColor.green,
  1034.                                               loColor.blue);
  1035.     }
  1036.     m_params[MAX_NS_COLORS+1].name = NULL;
  1037.     m_params[MAX_NS_COLORS+1].data = (void*)0;
  1038.  
  1039.     return m_params;
  1040. }
  1041.  
  1042. int
  1043. SetFontColorCommand::getParameterIndex(XFE_View* view)
  1044. {
  1045.     LO_Color color;
  1046.     int index;
  1047.  
  1048.     if (!isDeterminate(view, NULL))
  1049.         return -1;
  1050.  
  1051.     MWContext* context = view->getContext();
  1052.  
  1053.     if (fe_EditorColorGet(context, &color)) {
  1054.         index = EDT_GetMatchingFontColorIndex(&color);
  1055.     } else {
  1056.         index = 0; // default color.
  1057.     }
  1058.     return index;
  1059. }
  1060.  
  1061. void
  1062. SetFontColorCommand::setParameterIndex(XFE_View* view, unsigned index)
  1063. {
  1064.     MWContext* context = view->getContext();
  1065.     LO_Color color;
  1066.     unsigned n;
  1067.     XFE_CommandParameters* colors = getParameters(view);
  1068.  
  1069.     if (index == 0) {
  1070.         fe_EditorColorSet(context, NULL);
  1071.         return;
  1072.     }
  1073.  
  1074.     //
  1075.     //    Use this because the stupid back-end routine takes forever
  1076.     //    (yes ladies and gentlemen it re-parses the colors), and
  1077.     //    crashes a lot.
  1078.     //
  1079.     for (n = 1; n < index && colors[n].name != NULL; n++)
  1080.         ;
  1081.     
  1082.     if (colors[n].name != NULL) { // did not fall off end of list
  1083.         unsigned long word = (unsigned long)colors[n].data;
  1084.         color.red = WORD_TO_R(word);
  1085.         color.green = WORD_TO_G(word);
  1086.         color.blue = WORD_TO_B(word);
  1087.         fe_EditorColorSet(context, &color);
  1088.     }
  1089. }
  1090.  
  1091. void
  1092. SetFontColorCommand::reallyDoCommand(XFE_View* view, XFE_CommandInfo* info)
  1093. {
  1094.     uint8 red;
  1095.     uint8 green;
  1096.     uint8 blue;
  1097.     LO_Color color;
  1098.     if (info != NULL && *info->nparams > 0) {
  1099.         if (LO_ParseRGB(info->params[0], &red, &green, &blue)) {
  1100.             color.red = red;
  1101.             color.green = green;
  1102.             color.blue = blue;
  1103.             fe_EditorColorSet(view->getContext(), &color);
  1104.         }
  1105.     }
  1106. }
  1107.  
  1108. static parse_tokens_st paragraph_style_tokens[] = {
  1109.     { "normal",          P_NSDT       },
  1110.     { "headingOne",      P_HEADER_1   },
  1111.     { "headingTwo",      P_HEADER_2   },
  1112.     { "headingThree",    P_HEADER_3   },
  1113.     { "headingFour",     P_HEADER_4   },
  1114.     { "headingFive",     P_HEADER_5   },
  1115.     { "headingSix",      P_HEADER_6   },
  1116.     { "address",         P_ADDRESS    },
  1117.     { "formatted",       P_PREFORMAT  },
  1118.     { "listItem",        P_LIST_ITEM  },
  1119.     { "descriptionItem", P_DESC_TITLE },
  1120.     { "descriptionText", P_DESC_TEXT  },
  1121.     { 0 }
  1122. };
  1123.  
  1124. class SetParagraphStyleCommand : public AlwaysEnabledCommand
  1125. {
  1126. public:
  1127.     SetParagraphStyleCommand() :
  1128.         AlwaysEnabledCommand(xfeCmdSetParagraphStyle) {};
  1129.     SetParagraphStyleCommand(char* name) : AlwaysEnabledCommand(name) {};
  1130.  
  1131.     virtual XP_Bool isDynamic() { return TRUE; };
  1132.  
  1133.     XFE_CommandParameters* getParameters(XFE_View*) {
  1134.         return (XFE_CommandParameters*)paragraph_style_tokens;
  1135.     }
  1136.     int getParameterIndex(XFE_View* view) {
  1137.         TagType foo = fe_EditorParagraphPropertiesGet(view->getContext());
  1138.         return XFE_CommandParametersGetIndexByData(getParameters(view),
  1139.                                                    (void*)foo);
  1140.     }
  1141.     void    set(XFE_View* view, TagType type = P_NSDT) {
  1142.         fe_EditorParagraphPropertiesSet(view->getContext(), type);
  1143.     }
  1144.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*);
  1145. };
  1146.  
  1147. void
  1148. SetParagraphStyleCommand::reallyDoCommand(XFE_View* view, XFE_CommandInfo* info)
  1149. {
  1150.     TagType type = P_NSDT;
  1151.  
  1152.     if (info) {
  1153.         String* params = info->params;
  1154.         Cardinal nparams = *info->nparams;
  1155.         unsigned foo;
  1156.  
  1157.         if (nparams > 0) {
  1158.             if (tokens_cmp(paragraph_style_tokens, params[0], foo) != 0) {
  1159.                 type = (TagType)foo;
  1160.             } else {
  1161.                 FE_SYNTAX_ERROR();
  1162.                 return;
  1163.             }
  1164.         }
  1165.         
  1166.         set(view, type);
  1167.     }
  1168. }
  1169.  
  1170. static parse_tokens_st list_style_tokens[] = {
  1171.     { "unnumbered",      P_UNUM_LIST  },
  1172.     { "numbered",        P_NUM_LIST   },
  1173.     { "directory",       P_DIRECTORY  },
  1174.     { "menu",            P_MENU       },
  1175.     { "description",     P_DESC_LIST  },
  1176.     { 0 }
  1177. };
  1178.  
  1179. class SetListStyleCommand : public AlwaysEnabledCommand
  1180. {
  1181. public:
  1182.     SetListStyleCommand() :    AlwaysEnabledCommand(xfeCmdSetListStyle) {};
  1183.     SetListStyleCommand(char* name) : AlwaysEnabledCommand(name) {};
  1184.  
  1185.     void    set(XFE_View* view, TagType type = P_UNUM_LIST) {
  1186.         fe_EditorToggleList(view->getContext(), type);
  1187.     }
  1188.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo* calldata) {
  1189.         //   FIXME
  1190.         XFE_CommandInfo* info = (XFE_CommandInfo*)calldata;
  1191.         TagType type = P_UNUM_LIST;
  1192.  
  1193.         if (info) {
  1194.             String* params = info->params;
  1195.             Cardinal nparams = *info->nparams;
  1196.             unsigned foo;
  1197.  
  1198.             if (nparams > 0) {
  1199.                 if (tokens_cmp(list_style_tokens, params[0], foo) != 0) {
  1200.                     type = (TagType)foo;
  1201.                 } else {
  1202.                     FE_SYNTAX_ERROR();
  1203.                     return;
  1204.                 }
  1205.             }
  1206.  
  1207.             set(view, type);
  1208.         }
  1209.     };
  1210. };
  1211.  
  1212. static parse_tokens_st align_style_tokens[] = {
  1213.     { "left",      ED_ALIGN_LEFT  },
  1214.     { "center",    ED_ALIGN_ABSCENTER   },
  1215.     { "right",     ED_ALIGN_RIGHT  },
  1216.     { 0 }
  1217. };
  1218.  
  1219. class SetAlignStyleCommand : public AlwaysEnabledCommand
  1220. {
  1221. public:
  1222.     SetAlignStyleCommand() :    
  1223.         AlwaysEnabledCommand(xfeCmdSetAlignmentStyle) {};
  1224.     SetAlignStyleCommand(char* name) : AlwaysEnabledCommand(name) {};
  1225.  
  1226.     virtual XP_Bool isDynamic() { return TRUE; };
  1227.  
  1228.     XFE_CommandParameters* getParameters(XFE_View*) {
  1229.         return (XFE_CommandParameters*)align_style_tokens;
  1230.     }
  1231.     int getParameterIndex(XFE_View* view) {
  1232.         ED_Alignment align = fe_EditorAlignGet(view->getContext());
  1233.         int index;
  1234.  
  1235.         if (align == ED_ALIGN_LEFT)
  1236.             index = 0;
  1237.         else if (align == ED_ALIGN_ABSCENTER)
  1238.             index = 1;
  1239.         else if (align == ED_ALIGN_RIGHT)
  1240.             index = 2;
  1241.         else
  1242.             index = -1;
  1243.  
  1244.         return index;
  1245.     }
  1246.     void setParameterIndex(XFE_View* view, unsigned index) {
  1247.  
  1248.         if (index < 3) {
  1249.             ED_Alignment align = (ED_Alignment)align_style_tokens[index].bits;
  1250.             fe_EditorAlignSet(view->getContext(), align);
  1251.         }
  1252.     }
  1253.     void    set(XFE_View* view, ED_Alignment align = ED_ALIGN_LEFT) {
  1254.         fe_EditorAlignSet(view->getContext(), align);
  1255.     }
  1256.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo* info) {
  1257.         ED_Alignment align = ED_ALIGN_LEFT;
  1258.  
  1259.         if (info) {
  1260.             String* params = info->params;
  1261.             Cardinal nparams = *info->nparams;
  1262.             unsigned foo;
  1263.  
  1264.             if (nparams > 0) {
  1265.                 if (tokens_cmp(align_style_tokens, params[0], foo) != 0) {
  1266.                     align = (ED_Alignment)foo;
  1267.                 } else {
  1268.                     FE_SYNTAX_ERROR();
  1269.                     return;
  1270.                 }
  1271.             }
  1272.  
  1273.             set(view, align);
  1274.         }
  1275.     };
  1276. };
  1277.  
  1278. static parse_tokens_st char_style_tokens[] = {
  1279.     { "bold", TF_BOLD },
  1280.     { "italic", TF_ITALIC },
  1281.     { "underline", TF_UNDERLINE },
  1282.     { "fixed",  TF_FIXED },
  1283.     { "superscript",  TF_SUPER },
  1284.     { "subscript",    TF_SUB   },
  1285.     { "strikethrough", TF_STRIKEOUT },
  1286.     { "blink",  TF_BLINK },
  1287.     { "nobreak",  TF_NOBREAK },
  1288.     { "none",   TF_NONE }, /* probably does nothing, but TF_NONE may change */
  1289.     { 0 }
  1290. };
  1291.  
  1292. class SetCharacterStyleCommand : public AlwaysEnabledCommand
  1293. {
  1294. protected:
  1295.     unsigned parse_info(XFE_CommandInfo* info, unsigned& style);
  1296.  
  1297.     XP_Bool isDynamic() { return TRUE; };
  1298.  
  1299.     void    set(XFE_View* view, unsigned style = TF_NONE) {
  1300.         MWContext* context = view->getContext();
  1301.         
  1302.         if (style == TF_NONE)
  1303.             fe_EditorDoPoof(context);
  1304.         else
  1305.             fe_EditorCharacterPropertiesSet(context, style);
  1306.     }
  1307.     void    toggle(XFE_View* view, unsigned mask) {
  1308.         MWContext* context = view->getContext();
  1309.         unsigned values = (unsigned)fe_EditorCharacterPropertiesGet(context);
  1310.  
  1311.         values ^= mask;
  1312.  
  1313.         /*
  1314.          *    Super and Sub should be mutually exclusive.
  1315.          */
  1316.         if (mask == TF_SUPER && (values & TF_SUPER) != 0)
  1317.             values &= ~TF_SUB;
  1318.         else if (mask == TF_SUB && (values & TF_SUB) != 0)
  1319.             values &= ~TF_SUPER;
  1320.  
  1321.         fe_EditorCharacterPropertiesSet(context, values);
  1322.     }
  1323. public:
  1324.     SetCharacterStyleCommand() :    
  1325.         AlwaysEnabledCommand(xfeCmdSetCharacterStyle) {};
  1326.     SetCharacterStyleCommand(char* name) : AlwaysEnabledCommand(name) {};
  1327.  
  1328.     void reallyDoCommand(XFE_View* view, XFE_CommandInfo* calldata);
  1329. };
  1330.  
  1331. //
  1332. //    I don't know why, but the SCO C++ compiler seems to object to
  1333. //    (just) this function being inline. The compiler complains that
  1334. //    it cannot deal with the return statement, yet this function
  1335. //    is nearly identical to many other doCommand() methods in the
  1336. //    file! Huh? ...djw Jan/23/97
  1337. //
  1338. void
  1339. SetCharacterStyleCommand::reallyDoCommand(XFE_View* view, XFE_CommandInfo* calldata) {
  1340.  
  1341.     XFE_CommandInfo* info = (XFE_CommandInfo*)calldata;
  1342.     unsigned style = 0x0;
  1343.     
  1344.     if (parse_info(info, style) == 0) {
  1345.         FE_SYNTAX_ERROR();
  1346.         return;
  1347.     }
  1348.  
  1349.     set(view, style);
  1350. }
  1351.  
  1352. //
  1353. //  Here's another problem inline function for the HP-UX
  1354. //  and SCO C++ compilers.
  1355. //  They don't like the two return statements.  -slamm 2-3-97
  1356. //
  1357. unsigned
  1358. SetCharacterStyleCommand::parse_info(XFE_CommandInfo* info, unsigned& style) {
  1359.  
  1360.   style = 0x0;
  1361.   
  1362.   if (info) {
  1363.     String* params = info->params;
  1364.     Cardinal nparams = *info->nparams;
  1365.     
  1366.     if (nparams >= 1)
  1367.       return tokens_cmp(char_style_tokens, params[0], style);
  1368.   }
  1369.   return 0;
  1370. }
  1371.  
  1372.  
  1373. class ToggleCharacterStyleCommand : public SetCharacterStyleCommand
  1374. {
  1375. public:
  1376.     ToggleCharacterStyleCommand() :
  1377.         SetCharacterStyleCommand(xfeCmdToggleCharacterStyle) {};
  1378.  
  1379.     XP_Bool isDynamic() { return TRUE; };
  1380.  
  1381.        XP_Bool isSelected(XFE_View* view, XFE_CommandInfo* calldata);
  1382.  
  1383.     void reallyDoCommand(XFE_View* view, XFE_CommandInfo* calldata) {
  1384.         XFE_CommandInfo* info = (XFE_CommandInfo*)calldata;
  1385.         unsigned style = 0x0;
  1386.     
  1387.         if (parse_info((XFE_CommandInfo*)calldata, style) == 0) {
  1388.             FE_SYNTAX_ERROR();
  1389.         } else {
  1390.             toggle(view, style);
  1391.         }
  1392.     }
  1393. };
  1394.  
  1395. //
  1396. //  Here's another problem inline function for the HP-UX
  1397. //  and SCO C++ compilers.    -slamm 2-3-97
  1398. //
  1399. Boolean
  1400. ToggleCharacterStyleCommand::isSelected(XFE_View* view, XFE_CommandInfo* calldata) {
  1401.   XFE_CommandInfo* info = (XFE_CommandInfo*)calldata;
  1402.   unsigned style;
  1403.   
  1404.   if (parse_info(info, style) == 0) {
  1405.     FE_SYNTAX_ERROR();
  1406.     return False;
  1407.   }
  1408.   MWContext* context = view->getContext();
  1409.   
  1410.   return (style & fe_EditorCharacterPropertiesGet(context)) != 0;
  1411. }
  1412.  
  1413. class IndentCommand : public AlwaysEnabledCommand
  1414. {
  1415. public:
  1416.     IndentCommand() : AlwaysEnabledCommand(xfeCmdIndent) {};
  1417.  
  1418.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  1419.         fe_EditorIndent(view->getContext(), False);
  1420.     }
  1421. };
  1422.  
  1423. class OutdentCommand : public AlwaysEnabledCommand
  1424. {
  1425. public:
  1426.     OutdentCommand() : AlwaysEnabledCommand(xfeCmdOutdent) {};
  1427.  
  1428.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  1429.         fe_EditorIndent(view->getContext(), True);
  1430.     }
  1431. };
  1432.  
  1433. class SetObjectPropertiesCommand : public AlwaysEnabledCommand
  1434. {
  1435. public:
  1436.     SetObjectPropertiesCommand() :
  1437.         AlwaysEnabledCommand(xfeCmdSetObjectProperties) {};
  1438.  
  1439.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  1440.         fe_EditorObjectPropertiesDialogDo(view->getContext());
  1441.     }
  1442.     char*   getLabel(XFE_View* view, XFE_CommandInfo* info) {
  1443.  
  1444.         MWContext* context = view->getContext();
  1445.         char* name;
  1446.         ED_ElementType e_type = EDT_GetCurrentElementType(context);
  1447.  
  1448.         switch (e_type) {
  1449.         case ED_ELEMENT_HRULE:
  1450.             name = "hruleProperties";
  1451.             break;
  1452.         case ED_ELEMENT_IMAGE:
  1453.             name = "imageProperties";
  1454.             break;
  1455.         case ED_ELEMENT_UNKNOWN_TAG:
  1456.             name = "tagProperties";
  1457.             break;
  1458.         case ED_ELEMENT_TARGET:
  1459.             name = "targetProperties";
  1460.             break;
  1461.         default:
  1462.             name = "textProperties";
  1463.         }
  1464.  
  1465.         Widget widget = NULL;
  1466.  
  1467.         if (info != NULL)
  1468.             widget = info->widget;
  1469.  
  1470.         return view->getLabelString(name, widget);
  1471.     }
  1472. };
  1473.  
  1474. class SetPagePropertiesCommand : public AlwaysEnabledCommand
  1475. {
  1476. public:
  1477.     SetPagePropertiesCommand() : 
  1478.         AlwaysEnabledCommand(xfeCmdSetPageProperties) {};
  1479.  
  1480.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  1481.         fe_EditorDocumentPropertiesDialogDo(view->getContext(),
  1482.                                 XFE_EDITOR_DOCUMENT_PROPERTIES_APPEARANCE);
  1483.     }
  1484. };
  1485.  
  1486. class SetTablePropertiesCommand : public XFE_EditorViewCommand
  1487. {
  1488. public:
  1489.     SetTablePropertiesCommand() : XFE_EditorViewCommand(xfeCmdSetTableProperties) {};
  1490.  
  1491.     XP_Bool isEnabled(XFE_View* view, XFE_CommandInfo*) {
  1492.         return fe_EditorTableCanDelete(view->getContext());
  1493.     }
  1494.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  1495.         fe_EditorTablePropertiesDialogDo(view->getContext(),
  1496.                                          XFE_EDITOR_PROPERTIES_TABLE);
  1497.     }
  1498. };
  1499.  
  1500. #ifndef NO_SECURITY
  1501. class SetEncryptedCommand : public XFE_EditorViewCommand
  1502. {
  1503. public:
  1504.     SetEncryptedCommand() : XFE_EditorViewCommand(xfeCmdSetEncrypted) {};
  1505.  
  1506.     XP_Bool isDynamic() { return TRUE; };
  1507.  
  1508.        XP_Bool isSelected(XFE_View* view, XFE_CommandInfo* /*calldata*/) {
  1509.         return (XP_Bool) EDT_EncryptState(view->getContext());
  1510.     }
  1511.     XP_Bool isEnabled(XFE_View* /*view*/, XFE_CommandInfo*) {
  1512.         return (XP_Bool) PK11_TokenExists(CKM_SKIPJACK_CBC64);
  1513.     }
  1514.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  1515.         EDT_EncryptToggle(view->getContext());
  1516.                                          
  1517.     }
  1518. };
  1519. #endif
  1520.  
  1521. class SetCharacterColorCommand : public AlwaysEnabledCommand
  1522. {
  1523. public:
  1524.     SetCharacterColorCommand() :
  1525.         AlwaysEnabledCommand(xfeCmdSetCharacterColor) {};
  1526.  
  1527.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  1528.         fe_EditorSetColorsDialogDo(view->getContext());
  1529.     }
  1530. };
  1531.  
  1532. class JavaPluginCommand : public AlwaysEnabledCommand
  1533. {
  1534. private:
  1535.     int32 category_id;
  1536.     int32 plugin_id;
  1537. public:
  1538.     JavaPluginCommand(char* name, int32 cid, int32 pid) :
  1539.         AlwaysEnabledCommand(name) {
  1540.         category_id = cid;
  1541.         plugin_id = pid;
  1542.     }
  1543.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  1544.         EDT_PerformPlugin(view->getContext(), category_id, plugin_id, 0, 0);
  1545.     }
  1546.     char*   getLabel(XFE_View*, XFE_CommandInfo*) {
  1547.         return EDT_GetPluginName(category_id, plugin_id);
  1548.     };
  1549.     char*   getDocString(XFE_View*, XFE_CommandInfo*) {
  1550.         return EDT_GetPluginMenuHelp(category_id, plugin_id);
  1551.     };
  1552. };
  1553.  
  1554. class BrowsePageCommand : public AlwaysEnabledCommand
  1555. {
  1556. public:
  1557.     BrowsePageCommand() : AlwaysEnabledCommand(xfeCmdBrowsePage) {};
  1558.  
  1559.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*);
  1560. };
  1561.  
  1562. void    
  1563. BrowsePageCommand::reallyDoCommand(XFE_View* view, XFE_CommandInfo*)
  1564. {
  1565.     MWContext *context = view->getContext();
  1566.     URL_Struct *url;
  1567.  
  1568.     if (!FE_CheckAndSaveDocument(context))
  1569.         return;
  1570.  
  1571.     url = SHIST_CreateURLStructFromHistoryEntry(context,
  1572.                                             SHIST_GetCurrent(&context->hist));
  1573.     FE_GetURL(context, url);
  1574. }
  1575.  
  1576. class EditSourceCommand : public XFE_EditorViewCommand
  1577. {
  1578. public:
  1579.     EditSourceCommand() : XFE_EditorViewCommand(xfeCmdEditPageSource) {};
  1580.  
  1581.     XP_Bool isEnabled(XFE_View* view, XFE_CommandInfo*) {
  1582.         return fe_EditorDocumentIsSaved(view->getContext());
  1583.     }
  1584.  
  1585.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  1586.         fe_EditorEditSource(view->getContext());
  1587.     }
  1588. };
  1589.  
  1590. class ViewSourceCommand : public AlwaysEnabledCommand
  1591. {
  1592. public:
  1593.     ViewSourceCommand() : AlwaysEnabledCommand(xfeCmdViewPageSource) {};
  1594.  
  1595.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  1596.             fe_EditorDisplaySource(view->getContext());
  1597.     }
  1598. };
  1599.  
  1600. //
  1601. //    These should all go away, when commands can be properly paramaterized.
  1602. //
  1603. class SetFontSizeMinusTwoCommand : public SetFontSizeCommand
  1604. {
  1605. public:
  1606.     SetFontSizeMinusTwoCommand() :
  1607.                SetFontSizeCommand(xfeCmdSetFontSizeMinusTwo) {};
  1608.  
  1609.     XP_Bool isSelected(XFE_View* view, XFE_CommandInfo*) {
  1610.         MWContext* context = view->getContext();
  1611.         return fe_EditorFontSizeGet(context) == ED_FONTSIZE_MINUS_TWO;
  1612.     }
  1613.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  1614.         set(view, ED_FONTSIZE_MINUS_TWO);
  1615.     };
  1616. };
  1617.  
  1618. class SetFontSizeMinusOneCommand : public SetFontSizeCommand
  1619. {
  1620. public:
  1621.     SetFontSizeMinusOneCommand() :
  1622.         SetFontSizeCommand(xfeCmdSetFontSizeMinusOne) {};
  1623.  
  1624.     XP_Bool isSelected(XFE_View* view, XFE_CommandInfo*) {
  1625.         MWContext* context = view->getContext();
  1626.         return fe_EditorFontSizeGet(context) == ED_FONTSIZE_MINUS_ONE;
  1627.     }
  1628.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  1629.         set(view, ED_FONTSIZE_MINUS_ONE);
  1630.     };
  1631. };
  1632.  
  1633. class SetFontSizeZeroCommand : public SetFontSizeCommand
  1634. {
  1635. public:
  1636.     SetFontSizeZeroCommand() :
  1637.         SetFontSizeCommand(xfeCmdSetFontSizeZero) {};
  1638.  
  1639.     XP_Bool isSelected(XFE_View* view, XFE_CommandInfo*) {
  1640.         MWContext* context = view->getContext();
  1641.         return fe_EditorFontSizeGet(context) == ED_FONTSIZE_ZERO;
  1642.     }
  1643.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  1644.         set(view, ED_FONTSIZE_ZERO);
  1645.     };
  1646. };
  1647.  
  1648. class SetFontSizePlusOneCommand : public SetFontSizeCommand
  1649. {
  1650. public:
  1651.     SetFontSizePlusOneCommand() :
  1652.         SetFontSizeCommand(xfeCmdSetFontSizePlusOne) {};
  1653.  
  1654.     XP_Bool isSelected(XFE_View* view, XFE_CommandInfo*) {
  1655.         MWContext* context = view->getContext();
  1656.         return fe_EditorFontSizeGet(context) == ED_FONTSIZE_PLUS_ONE;
  1657.     }
  1658.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  1659.         set(view, ED_FONTSIZE_PLUS_ONE);
  1660.     };
  1661. };
  1662.  
  1663. class SetFontSizePlusTwoCommand : public SetFontSizeCommand
  1664. {
  1665. public:
  1666.     SetFontSizePlusTwoCommand() :
  1667.         SetFontSizeCommand(xfeCmdSetFontSizePlusTwo) {};
  1668.  
  1669.     XP_Bool isSelected(XFE_View* view, XFE_CommandInfo*) {
  1670.         MWContext* context = view->getContext();
  1671.         return fe_EditorFontSizeGet(context) == ED_FONTSIZE_PLUS_TWO;
  1672.     }
  1673.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  1674.         set(view, ED_FONTSIZE_PLUS_TWO);
  1675.     };
  1676. };
  1677.  
  1678. class SetFontSizePlusThreeCommand : public SetFontSizeCommand
  1679. {
  1680. public:
  1681.     SetFontSizePlusThreeCommand() :
  1682.         SetFontSizeCommand(xfeCmdSetFontSizePlusThree) {};
  1683.  
  1684.     XP_Bool isSelected(XFE_View* view, XFE_CommandInfo*) {
  1685.         MWContext* context = view->getContext();
  1686.         return fe_EditorFontSizeGet(context) == ED_FONTSIZE_PLUS_THREE;
  1687.     }
  1688.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  1689.         set(view, ED_FONTSIZE_PLUS_THREE);
  1690.     };
  1691. };
  1692.  
  1693. class SetFontSizePlusFourCommand : public SetFontSizeCommand
  1694. {
  1695. public:
  1696.     SetFontSizePlusFourCommand() :
  1697.         SetFontSizeCommand(xfeCmdSetFontSizePlusFour) {};
  1698.  
  1699.     XP_Bool isSelected(XFE_View* view, XFE_CommandInfo*) {
  1700.         MWContext* context = view->getContext();
  1701.         return fe_EditorFontSizeGet(context) == ED_FONTSIZE_PLUS_FOUR;
  1702.     }
  1703.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  1704.         set(view, ED_FONTSIZE_PLUS_FOUR);
  1705.     };
  1706. };
  1707.  
  1708. class SetParagraphStyleNormalCommand : public SetParagraphStyleCommand
  1709. {
  1710. public:
  1711.     SetParagraphStyleNormalCommand() :
  1712.         SetParagraphStyleCommand(xfeCmdSetParagraphStyleNormal) {};
  1713.  
  1714.     XP_Bool isSelected(XFE_View* view, XFE_CommandInfo*) {
  1715.         MWContext* context = view->getContext();
  1716.         return fe_EditorParagraphPropertiesGet(context) == P_NSDT;
  1717.     }
  1718.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  1719.         set(view);
  1720.     };
  1721. };
  1722.  
  1723. class SetParagraphStyleHeadingOneCommand : public SetParagraphStyleCommand
  1724. {
  1725. public:
  1726.     SetParagraphStyleHeadingOneCommand() :
  1727.         SetParagraphStyleCommand(xfeCmdSetParagraphStyleHeadingOne) {};
  1728.  
  1729.     XP_Bool isSelected(XFE_View* view, XFE_CommandInfo*) {
  1730.         MWContext* context = view->getContext();
  1731.         return fe_EditorParagraphPropertiesGet(context) == P_HEADER_1;
  1732.     }
  1733.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  1734.         set(view, P_HEADER_1);
  1735.     };
  1736. };
  1737.  
  1738. class SetParagraphStyleHeadingTwoCommand : public SetParagraphStyleCommand
  1739. {
  1740. public:
  1741.     SetParagraphStyleHeadingTwoCommand() :
  1742.         SetParagraphStyleCommand(xfeCmdSetParagraphStyleHeadingTwo) {};
  1743.  
  1744.     XP_Bool isSelected(XFE_View* view, XFE_CommandInfo*) {
  1745.         MWContext* context = view->getContext();
  1746.         return fe_EditorParagraphPropertiesGet(context) == P_HEADER_2;
  1747.     }
  1748.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  1749.         set(view, P_HEADER_2);
  1750.     };
  1751. };
  1752.  
  1753. class SetParagraphStyleHeadingThreeCommand : public SetParagraphStyleCommand
  1754. {
  1755. public:
  1756.     SetParagraphStyleHeadingThreeCommand() :
  1757.         SetParagraphStyleCommand(xfeCmdSetParagraphStyleHeadingThree) {};
  1758.  
  1759.     XP_Bool isSelected(XFE_View* view, XFE_CommandInfo*) {
  1760.         MWContext* context = view->getContext();
  1761.         return fe_EditorParagraphPropertiesGet(context) == P_HEADER_3;
  1762.     }
  1763.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  1764.         set(view, P_HEADER_3);
  1765.     };
  1766. };
  1767.  
  1768. class SetParagraphStyleHeadingFourCommand : public SetParagraphStyleCommand
  1769. {
  1770. public:
  1771.     SetParagraphStyleHeadingFourCommand() :
  1772.         SetParagraphStyleCommand(xfeCmdSetParagraphStyleHeadingFour) {};
  1773.  
  1774.     XP_Bool isSelected(XFE_View* view, XFE_CommandInfo*) {
  1775.         MWContext* context = view->getContext();
  1776.         return fe_EditorParagraphPropertiesGet(context) == P_HEADER_4;
  1777.     }
  1778.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  1779.         set(view, P_HEADER_4);
  1780.     };
  1781. };
  1782.  
  1783. class SetParagraphStyleHeadingFiveCommand : public SetParagraphStyleCommand
  1784. {
  1785. public:
  1786.     SetParagraphStyleHeadingFiveCommand() :
  1787.         SetParagraphStyleCommand(xfeCmdSetParagraphStyleHeadingFive) {};
  1788.  
  1789.     XP_Bool isSelected(XFE_View* view, XFE_CommandInfo*) {
  1790.         MWContext* context = view->getContext();
  1791.         return fe_EditorParagraphPropertiesGet(context) == P_HEADER_5;
  1792.     }
  1793.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  1794.         set(view, P_HEADER_5);
  1795.     };
  1796. };
  1797.  
  1798. class SetParagraphStyleHeadingSixCommand : public SetParagraphStyleCommand
  1799. {
  1800. public:
  1801.     SetParagraphStyleHeadingSixCommand() :
  1802.         SetParagraphStyleCommand(xfeCmdSetParagraphStyleHeadingSix) {};
  1803.  
  1804.     XP_Bool isSelected(XFE_View* view, XFE_CommandInfo*) {
  1805.         MWContext* context = view->getContext();
  1806.         return fe_EditorParagraphPropertiesGet(context) == P_HEADER_6;
  1807.     }
  1808.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  1809.         set(view, P_HEADER_6);
  1810.     };
  1811. };
  1812.  
  1813. class SetParagraphStyleAddressCommand : public SetParagraphStyleCommand
  1814. {
  1815. public:
  1816.     SetParagraphStyleAddressCommand() :
  1817.         SetParagraphStyleCommand(xfeCmdSetParagraphStyleAddress) {};
  1818.  
  1819.     XP_Bool isSelected(XFE_View* view, XFE_CommandInfo*) {
  1820.         MWContext* context = view->getContext();
  1821.         return fe_EditorParagraphPropertiesGet(context) == P_ADDRESS;
  1822.     }
  1823.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  1824.         set(view, P_ADDRESS);
  1825.     };
  1826. };
  1827.  
  1828. class SetParagraphStyleFormattedCommand : public SetParagraphStyleCommand
  1829. {
  1830. public:
  1831.     SetParagraphStyleFormattedCommand() :
  1832.         SetParagraphStyleCommand(xfeCmdSetParagraphStyleFormatted) {};
  1833.  
  1834.     XP_Bool isSelected(XFE_View* view, XFE_CommandInfo*) {
  1835.         MWContext* context = view->getContext();
  1836.         return fe_EditorParagraphPropertiesGet(context) == P_PREFORMAT;
  1837.     }
  1838.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  1839.         set(view, P_PREFORMAT);
  1840.     };
  1841. };
  1842.  
  1843. class SetParagraphStyleTitleCommand : public SetParagraphStyleCommand
  1844. {
  1845. public:
  1846.     SetParagraphStyleTitleCommand() :
  1847.         SetParagraphStyleCommand(xfeCmdSetParagraphStyleDescriptionTitle) {};
  1848.  
  1849.     XP_Bool isSelected(XFE_View* view, XFE_CommandInfo*) {
  1850.         MWContext* context = view->getContext();
  1851.         return fe_EditorParagraphPropertiesGet(context) == P_DESC_TITLE;
  1852.     }
  1853.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  1854.         set(view, P_DESC_TITLE);
  1855.     };
  1856. };
  1857.  
  1858. class SetParagraphStyleTextCommand : public SetParagraphStyleCommand
  1859. {
  1860. public:
  1861.     SetParagraphStyleTextCommand() :
  1862.         SetParagraphStyleCommand(xfeCmdSetParagraphStyleDescriptionText) {};
  1863.  
  1864.     XP_Bool isSelected(XFE_View* view, XFE_CommandInfo*) {
  1865.         MWContext* context = view->getContext();
  1866.         return fe_EditorParagraphPropertiesGet(context) == P_DESC_TEXT;
  1867.     }
  1868.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  1869.         set(view, P_DESC_TEXT);
  1870.     };
  1871. };
  1872.  
  1873. class SetParagraphStyleBlockQuoteCommand : public SetParagraphStyleCommand
  1874. {
  1875. public:
  1876.     SetParagraphStyleBlockQuoteCommand() :
  1877.         SetParagraphStyleCommand(xfeCmdSetParagraphStyleBlockQuote) {};
  1878.     
  1879.     XP_Bool isSelected(XFE_View* view, XFE_CommandInfo*) {
  1880.         MWContext* context = view->getContext();
  1881.         return fe_EditorParagraphPropertiesGet(context) == P_BLOCKQUOTE;
  1882.     }
  1883.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  1884.         set(view, P_BLOCKQUOTE);
  1885.     };
  1886. };
  1887.  
  1888. class SetListStyleNoneCommand : public SetListStyleCommand
  1889. {
  1890. public:
  1891.     SetListStyleNoneCommand() :
  1892.         SetListStyleCommand(xfeCmdSetListStyleNone) {};
  1893.  
  1894.     XP_Bool isSelected(XFE_View* view, XFE_CommandInfo*) {
  1895.         MWContext* context = view->getContext();
  1896.         TagType    p_type;
  1897.  
  1898.         fe_EditorParagraphPropertiesGetAll(context, &p_type, NULL, NULL);
  1899.  
  1900.         return p_type != P_LIST_ITEM;
  1901.     }
  1902.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  1903.         MWContext* context = view->getContext();
  1904.         
  1905.         fe_EditorParagraphPropertiesSetAll(context,
  1906.                                            P_NSDT,
  1907.                                            NULL,
  1908.                                            fe_EditorAlignGet(context));
  1909.     };
  1910. };
  1911.  
  1912. class SetListStyleBulletedCommand : public SetListStyleCommand
  1913. {
  1914. public:
  1915.     SetListStyleBulletedCommand() :
  1916.         SetListStyleCommand(xfeCmdSetListStyleBulleted) {};
  1917.  
  1918.     XP_Bool isSelected(XFE_View* view, XFE_CommandInfo*) {
  1919.         MWContext* context = view->getContext();
  1920.         TagType    p_type;
  1921.         EDT_ListData l_data;
  1922.  
  1923.         fe_EditorParagraphPropertiesGetAll(context, &p_type, &l_data, NULL);
  1924.  
  1925.         return (p_type == P_LIST_ITEM) && (l_data.iTagType == P_UNUM_LIST);
  1926.     }
  1927.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  1928.         set(view, P_UNUM_LIST);
  1929.     };
  1930. };
  1931.  
  1932. class SetListStyleNumberedCommand : public SetListStyleCommand
  1933. {
  1934. public:
  1935.     SetListStyleNumberedCommand() :
  1936.         SetListStyleCommand(xfeCmdSetListStyleNumbered) {};
  1937.  
  1938.     XP_Bool isSelected(XFE_View* view, XFE_CommandInfo*) {
  1939.         MWContext* context = view->getContext();
  1940.         TagType    p_type;
  1941.         EDT_ListData l_data;
  1942.  
  1943.         fe_EditorParagraphPropertiesGetAll(context, &p_type, &l_data, NULL);
  1944.  
  1945.         return (p_type == P_LIST_ITEM) && (l_data.iTagType == P_NUM_LIST);
  1946.     }
  1947.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  1948.         set(view, P_NUM_LIST);
  1949.     };
  1950. };
  1951.  
  1952. class SetAlignStyleLeftCommand : public SetAlignStyleCommand
  1953. {
  1954. public:
  1955.     SetAlignStyleLeftCommand() :
  1956.         SetAlignStyleCommand(xfeCmdSetAlignmentStyleLeft) {};
  1957.  
  1958.     XP_Bool isSelected(XFE_View* view, XFE_CommandInfo*) {
  1959.         return fe_EditorAlignGet(view->getContext()) == ED_ALIGN_LEFT;
  1960.     }
  1961.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  1962.         set(view, ED_ALIGN_LEFT);
  1963.     };
  1964. };
  1965.  
  1966. class SetAlignStyleCenterCommand : public SetAlignStyleCommand
  1967. {
  1968. public:
  1969.     SetAlignStyleCenterCommand() :
  1970.         SetAlignStyleCommand(xfeCmdSetAlignmentStyleCenter) {};
  1971.  
  1972.     XP_Bool isSelected(XFE_View* view, XFE_CommandInfo*) {
  1973.         return fe_EditorAlignGet(view->getContext()) == ED_ALIGN_ABSCENTER;
  1974.     }
  1975.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  1976.         set(view, ED_ALIGN_ABSCENTER);
  1977.     };
  1978. };
  1979.  
  1980. class SetAlignStyleRightCommand : public SetAlignStyleCommand
  1981. {
  1982. public:
  1983.     SetAlignStyleRightCommand() :
  1984.         SetAlignStyleCommand(xfeCmdSetAlignmentStyleRight) {};
  1985.  
  1986.     XP_Bool isSelected(XFE_View* view, XFE_CommandInfo*) {
  1987.         return fe_EditorAlignGet(view->getContext()) == ED_ALIGN_RIGHT;
  1988.     }
  1989.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  1990.         set(view, ED_ALIGN_RIGHT);
  1991.     };
  1992. };
  1993.  
  1994. class ClearAllStylesCommand : public SetCharacterStyleCommand
  1995. {
  1996. public:
  1997.     ClearAllStylesCommand() :
  1998.         SetCharacterStyleCommand(xfeCmdClearAllStyles) {};
  1999.  
  2000.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  2001.         set(view, TF_NONE);
  2002.     };
  2003. };
  2004.  
  2005. class ToggleCharacterStyleBoldCommand : public SetCharacterStyleCommand
  2006. {
  2007. public:
  2008.     ToggleCharacterStyleBoldCommand() :
  2009.         SetCharacterStyleCommand(xfeCmdToggleCharacterStyleBold) {};
  2010.  
  2011.     XP_Bool isDeterminate(XFE_View* view, XFE_CommandInfo*) {
  2012.         return style_is_determinate(view->getContext(), TF_BOLD);
  2013.     };
  2014.        XP_Bool isSelected(XFE_View* view, XFE_CommandInfo*) {
  2015.         MWContext* context = view->getContext();
  2016.  
  2017.         return (TF_BOLD & fe_EditorCharacterPropertiesGet(context)) != 0;
  2018.     };
  2019.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  2020.         toggle(view, TF_BOLD);
  2021.     };
  2022. };
  2023.  
  2024. class ToggleCharacterStyleUnderlineCommand : public SetCharacterStyleCommand
  2025. {
  2026. public:
  2027.     ToggleCharacterStyleUnderlineCommand() :
  2028.         SetCharacterStyleCommand(xfeCmdToggleCharacterStyleUnderline) {};
  2029.  
  2030.     XP_Bool isDeterminate(XFE_View* view, XFE_CommandInfo*) {
  2031.         return style_is_determinate(view->getContext(), TF_UNDERLINE);
  2032.     };
  2033.        XP_Bool isSelected(XFE_View* view, XFE_CommandInfo*) {
  2034.         MWContext* context = view->getContext();
  2035.  
  2036.         return (TF_UNDERLINE & fe_EditorCharacterPropertiesGet(context)) != 0;
  2037.     };
  2038.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  2039.         toggle(view, TF_UNDERLINE);
  2040.     };
  2041. };
  2042.  
  2043. class ToggleCharacterStyleItalicCommand : public SetCharacterStyleCommand
  2044. {
  2045. public:
  2046.     ToggleCharacterStyleItalicCommand() :
  2047.         SetCharacterStyleCommand(xfeCmdToggleCharacterStyleItalic) {};
  2048.  
  2049.     XP_Bool isDeterminate(XFE_View* view, XFE_CommandInfo*) {
  2050.         return style_is_determinate(view->getContext(), TF_ITALIC);
  2051.     };
  2052.        XP_Bool isSelected(XFE_View* view, XFE_CommandInfo*) {
  2053.         MWContext* context = view->getContext();
  2054.  
  2055.         return (TF_ITALIC & fe_EditorCharacterPropertiesGet(context)) != 0;
  2056.     };
  2057.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  2058.         toggle(view, TF_ITALIC);
  2059.     };
  2060. };
  2061.  
  2062. class ToggleCharacterStyleFixedCommand : public SetCharacterStyleCommand
  2063. {
  2064. public:
  2065.     ToggleCharacterStyleFixedCommand() :
  2066.         SetCharacterStyleCommand(xfeCmdToggleCharacterStyleFixed) {};
  2067.  
  2068.        XP_Bool isSelected(XFE_View* view, XFE_CommandInfo*) {
  2069.         MWContext* context = view->getContext();
  2070.  
  2071.         return (TF_FIXED & fe_EditorCharacterPropertiesGet(context)) != 0;
  2072.     };
  2073.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  2074.         toggle(view, TF_FIXED);
  2075.     };
  2076. };
  2077.  
  2078. class ToggleCharacterStyleSuperscriptCommand : public SetCharacterStyleCommand
  2079. {
  2080. public:
  2081.     ToggleCharacterStyleSuperscriptCommand() :
  2082.         SetCharacterStyleCommand(xfeCmdToggleCharacterStyleSuperscript)
  2083.     {};
  2084.  
  2085.        XP_Bool isSelected(XFE_View* view, XFE_CommandInfo*) {
  2086.         MWContext* context = view->getContext();
  2087.  
  2088.         return (TF_SUPER & fe_EditorCharacterPropertiesGet(context)) != 0;
  2089.     };
  2090.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  2091.         toggle(view, TF_SUPER);
  2092.     };
  2093. };
  2094.  
  2095. class ToggleCharacterStyleSubscriptCommand : public SetCharacterStyleCommand
  2096. {
  2097. public:
  2098.     ToggleCharacterStyleSubscriptCommand() :
  2099.         SetCharacterStyleCommand(xfeCmdToggleCharacterStyleSubscript)
  2100.     {};
  2101.  
  2102.        XP_Bool isSelected(XFE_View* view, XFE_CommandInfo*) {
  2103.         MWContext* context = view->getContext();
  2104.  
  2105.         return (TF_SUB & fe_EditorCharacterPropertiesGet(context)) != 0;
  2106.     };
  2107.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  2108.         toggle(view, TF_SUB);
  2109.     };
  2110. };
  2111.  
  2112. class ToggleCharacterStyleStrikethroughCommand :
  2113.     public SetCharacterStyleCommand
  2114. {
  2115. public:
  2116.     ToggleCharacterStyleStrikethroughCommand() :
  2117.     SetCharacterStyleCommand(xfeCmdToggleCharacterStyleStrikethrough) {
  2118.     };
  2119.  
  2120.        XP_Bool isSelected(XFE_View* view, XFE_CommandInfo*) {
  2121.         MWContext* context = view->getContext();
  2122.  
  2123.         return (TF_STRIKEOUT & fe_EditorCharacterPropertiesGet(context))
  2124.             != 0;
  2125.     };
  2126.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  2127.         toggle(view, TF_STRIKEOUT);
  2128.     };
  2129. };
  2130.  
  2131. class ToggleCharacterStyleBlinkCommand : public SetCharacterStyleCommand
  2132. {
  2133. public:
  2134.     ToggleCharacterStyleBlinkCommand() :
  2135.         SetCharacterStyleCommand(xfeCmdToggleCharacterStyleBlink) {};
  2136.  
  2137.        XP_Bool isSelected(XFE_View* view, XFE_CommandInfo*) {
  2138.         MWContext* context = view->getContext();
  2139.  
  2140.         return (TF_BLINK & fe_EditorCharacterPropertiesGet(context)) != 0;
  2141.     };
  2142.     void    reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  2143.         toggle(view, TF_BLINK);
  2144.     };
  2145. };
  2146.  
  2147. enum {
  2148.     MOVE_NOWHERE = 0,
  2149.     MOVE_UP,       // previous line
  2150.     MOVE_DOWN,
  2151.     MOVE_NEXT,     // character
  2152.     MOVE_PREVIOUS, // character
  2153.     MOVE_BEGINNING_OF_LINE,
  2154.     MOVE_END_OF_LINE,
  2155.     MOVE_BEGINNING_OF_DOCUMENT,
  2156.     MOVE_END_OF_DOCUMENT,
  2157.     MOVE_NEXT_WORD,
  2158.     MOVE_PREVIOUS_WORD,
  2159.     MOVE_NEXT_TABLE_CELL,
  2160.     MOVE_PREVIOUS_TABLE_CELL
  2161. } MoveCommandDirection_t;
  2162.  
  2163. static parse_tokens_st move_command_directions[] = {
  2164.     { "next",            MOVE_NEXT },
  2165.     { "previous",        MOVE_PREVIOUS },
  2166.     { "up",              MOVE_UP },
  2167.     { "previousLine",    MOVE_UP },
  2168.     { "down",            MOVE_DOWN },
  2169.     { "nextLine",        MOVE_DOWN },
  2170.     { "beginningOfLine", MOVE_BEGINNING_OF_LINE },
  2171.     { "beginOfLine",     MOVE_BEGINNING_OF_LINE },
  2172.     { "endOfLine",       MOVE_END_OF_LINE },
  2173.     { "beginningOfPage", MOVE_BEGINNING_OF_DOCUMENT },
  2174.     { "endOfPage",       MOVE_END_OF_DOCUMENT },
  2175.     { "nextWord",        MOVE_NEXT_WORD },
  2176.     { "previousWord",    MOVE_PREVIOUS_WORD },
  2177.     { "nextCell",        MOVE_NEXT_TABLE_CELL },
  2178.     { "previousCell",    MOVE_PREVIOUS_TABLE_CELL },
  2179.     { 0 },
  2180. };
  2181.  
  2182. class MoveCommand : public AlwaysEnabledCommand
  2183. {
  2184. public:
  2185.     MoveCommand() :    AlwaysEnabledCommand(xfeCmdMoveCursor) {};
  2186.  
  2187.     virtual XP_Bool isSlow() {
  2188.         return FALSE;
  2189.     };
  2190.     void reallyDoCommand(XFE_View* view, XFE_CommandInfo* info) {
  2191.         
  2192.         unsigned direction = MOVE_NOWHERE;
  2193.         MWContext* context = view->getContext();
  2194.  
  2195.         if (info != NULL && *info->nparams > 0) {
  2196.             char* param = info->params[0];
  2197.  
  2198.             if (tokens_cmp(move_command_directions, param, direction) != 1)
  2199.                 direction = MOVE_NOWHERE;
  2200.         }
  2201.  
  2202.         Boolean shifted, ctrl;
  2203.         xfe_GetShiftAndCtrl(info->event, &shifted, &ctrl);
  2204.  
  2205.         switch (direction) {
  2206.         case MOVE_UP:       // previous line
  2207.             EDT_Up(context, shifted); break;
  2208.         case MOVE_DOWN:
  2209.             EDT_Down(context, shifted); break;
  2210.         case MOVE_NEXT:     // character
  2211.             EDT_NextChar(context, shifted); break;
  2212.         case MOVE_PREVIOUS: // character
  2213.             EDT_PreviousChar(context, shifted); break;
  2214.         case MOVE_BEGINNING_OF_LINE:
  2215.             EDT_BeginOfLine(context, shifted); break;
  2216.         case MOVE_END_OF_LINE:
  2217.             EDT_EndOfLine(context, shifted); break;
  2218.         case MOVE_BEGINNING_OF_DOCUMENT:
  2219.             EDT_BeginOfDocument(context, shifted); break;
  2220.         case MOVE_END_OF_DOCUMENT:
  2221.             EDT_EndOfDocument(context, shifted); break;
  2222.         case MOVE_NEXT_WORD:
  2223.             EDT_NextWord(context, shifted); break;
  2224.         case MOVE_PREVIOUS_WORD:
  2225.             EDT_PreviousWord(context, shifted); break;
  2226.         case MOVE_NEXT_TABLE_CELL:
  2227.             EDT_NextTableCell(context, shifted); break;
  2228.         case MOVE_PREVIOUS_TABLE_CELL:
  2229.             EDT_PreviousTableCell(context, shifted); break;
  2230.         default:
  2231.             FE_SYNTAX_ERROR();
  2232.         }
  2233.     };
  2234. };
  2235.  
  2236. class KeyInsertCommand : public AlwaysEnabledCommand
  2237. {
  2238. public:
  2239.     KeyInsertCommand() :    AlwaysEnabledCommand(xfeCmdKeyInsert) {};
  2240.  
  2241.     virtual XP_Bool requiresChromeUpdate() {
  2242.         return FALSE;
  2243.     };
  2244.     virtual XP_Bool isSlow() {
  2245.         return FALSE;
  2246.     };
  2247.     void reallyDoCommand(XFE_View* view, XFE_CommandInfo* info) {
  2248.         MWContext* context = view->getContext();
  2249.         if (info != NULL) {
  2250.             fe_EditorKeyInsert(context, info->widget, info->event);
  2251.         }
  2252.     };
  2253. };
  2254.  
  2255. class InsertReturnCommand : public AlwaysEnabledCommand
  2256. {
  2257. public:
  2258.     InsertReturnCommand() :    AlwaysEnabledCommand(xfeCmdInsertReturn) {};
  2259.  
  2260.     virtual XP_Bool isSlow() {
  2261.         return FALSE;
  2262.     };
  2263.     void reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  2264.         MWContext* context = view->getContext();
  2265.         EDT_ReturnKey(context);
  2266.     };
  2267. };
  2268.  
  2269. static parse_tokens_st insert_line_break_types[] = {
  2270.     { "normal", (unsigned)ED_BREAK_NORMAL },
  2271.     { "left",   (unsigned)ED_BREAK_LEFT   },
  2272.     { "right",  (unsigned)ED_BREAK_RIGHT  },
  2273.     { "both",   (unsigned)ED_BREAK_BOTH   },
  2274.     { NULL }
  2275. };
  2276.  
  2277. class InsertLineBreakCommand : public AlwaysEnabledCommand
  2278. {
  2279. public:
  2280.     InsertLineBreakCommand() : AlwaysEnabledCommand(xfeCmdInsertLineBreak) {};
  2281.     
  2282.     void reallyDoCommand(XFE_View* view, XFE_CommandInfo* info) {
  2283.         ED_BreakType type = ED_BREAK_NORMAL;
  2284.         MWContext* context = view->getContext();
  2285.         
  2286.         if (info != NULL && *info->nparams > 0) {
  2287.             char* param = info->params[0];
  2288.             unsigned foo;
  2289.  
  2290.             if (tokens_cmp(insert_line_break_types, param, foo) != 1)
  2291.                 type = (ED_BreakType)-1;
  2292.             else
  2293.                 type = (ED_BreakType)foo;
  2294.         }
  2295.         
  2296.         switch (type) {
  2297.         case ED_BREAK_NORMAL:
  2298.         case ED_BREAK_LEFT:
  2299.         case ED_BREAK_RIGHT:
  2300.         case ED_BREAK_BOTH:
  2301.             fe_EditorLineBreak(context, type);
  2302.             break;
  2303.         default:
  2304.             FE_SYNTAX_ERROR();
  2305.         }
  2306.     };
  2307. };
  2308.  
  2309. class TabCommand : public AlwaysEnabledCommand
  2310. {
  2311. public:
  2312.     TabCommand() : AlwaysEnabledCommand(xfeCmdTab) {};
  2313.  
  2314.     virtual XP_Bool isSlow() {
  2315.         return FALSE;
  2316.     };
  2317.  
  2318.     virtual void reallyDoCommand(XFE_View* view, XFE_CommandInfo* info) {
  2319.  
  2320.         Boolean forward = TRUE;
  2321.         Boolean force = FALSE;
  2322.         Boolean error = FALSE;
  2323.  
  2324.         if (info != NULL && *info->nparams > 0) {
  2325.             if (XP_STRCASECMP(info->params[0], "forward") == 0)
  2326.                 forward = TRUE;
  2327.             else if (XP_STRCASECMP(info->params[0], "backward") == 0)
  2328.                 forward = FALSE;
  2329.             else if (XP_STRCASECMP(info->params[0], "insert") == 0)
  2330.                 force = TRUE;
  2331.             else {
  2332.                 error = TRUE;
  2333.                 FE_SYNTAX_ERROR();
  2334.             }
  2335.         }
  2336.         if (!error)
  2337.             fe_EditorTab(view->getContext(), forward, force);
  2338.     }; 
  2339. };
  2340.  
  2341. class SelectCommand : public XFE_ViewCommand
  2342. {
  2343. public:
  2344.     SelectCommand() : XFE_ViewCommand(xfeCmdSelect) {};
  2345.     
  2346.     virtual XP_Bool isSlow() {
  2347.         return FALSE;
  2348.     };
  2349.  
  2350.     //
  2351.     //    This guy impliments doCommand() itself so that it can manage
  2352.     //    update chrome dynamically.
  2353.     //
  2354.     void    doCommand(XFE_View* view, XFE_CommandInfo* info);
  2355. };
  2356.  
  2357. void
  2358. SelectCommand::doCommand(XFE_View* view, XFE_CommandInfo* info) {
  2359.     MWContext* context = view->getContext();
  2360.     
  2361.     if (info != NULL && *info->nparams > 0) {
  2362.         char*    param = info->params[0];
  2363.         unsigned do_chrome = 0;
  2364.         
  2365.         if (XP_STRCASECMP(param, "grab") == 0) {
  2366.             fe_EditorGrabFocus(context, info->event);
  2367.             do_chrome++;
  2368.         } else if (XP_STRCASECMP(param, "begin") == 0) {
  2369.             fe_EditorSelectionBegin(context, info->event);
  2370.             do_chrome++;
  2371.         } else if (XP_STRCASECMP(param, "extend") == 0) {
  2372.             fe_EditorSelectionExtend(context, info->event);
  2373.         } else if (XP_STRCASECMP(param, "end") == 0) {
  2374.             fe_EditorSelectionEnd(context, info->event);
  2375.             do_chrome++;
  2376.         } else if (XP_STRCASECMP(param, "word") == 0) {
  2377.             unsigned long x;
  2378.             unsigned long y;
  2379.             fe_EventLOCoords(context, info->event, &x, &y);
  2380.             EDT_DoubleClick(context, x, y); /* this takes screen co-ords?? */
  2381.             do_chrome++;
  2382.         } else {
  2383.             FE_SYNTAX_ERROR();
  2384.         }
  2385.         
  2386.         if (do_chrome != 0) {
  2387.             XFE_Component* top = view->getToplevel();
  2388.             top->notifyInterested(XFE_View::chromeNeedsUpdating);
  2389.         }
  2390.     }
  2391. }
  2392.  
  2393. class EditorObjectIsCommand : public XFE_ObjectIsCommand
  2394. {
  2395. public:
  2396.     char* getObjectType(XFE_View*);
  2397. };
  2398.  
  2399. char*
  2400. EditorObjectIsCommand::getObjectType(XFE_View* view)
  2401. {
  2402.     ED_ElementType e_type; /* jag */
  2403.     
  2404.     e_type = EDT_GetCurrentElementType(view->getContext());
  2405.     
  2406.     switch (e_type) {
  2407.     case ED_ELEMENT_TEXT:        return "text";
  2408.     case ED_ELEMENT_IMAGE:       return "image";
  2409.     case ED_ELEMENT_UNKNOWN_TAG: return "tag";
  2410.     case ED_ELEMENT_TARGET:      return "target";
  2411.     case ED_ELEMENT_HRULE:       return "hrule";
  2412.     default:                     return "unknown";
  2413.     }
  2414. }
  2415.  
  2416. class DialogCommand : public XFE_ViewCommand
  2417. {
  2418. public:
  2419.     DialogCommand() : XFE_ViewCommand(xfeCmdDialog) {};
  2420.     
  2421.     void doCommand(XFE_View* view, XFE_CommandInfo* info) {
  2422.  
  2423.         MWContext* context = view->getContext();
  2424.         unsigned   nerrors = 0;
  2425.         String*    av = info->params;
  2426.  
  2427.         if (info != NULL && *info->nparams == 1) {
  2428.             if (XP_STRCASECMP(av[0], "text") == 0)
  2429.                 fe_EditorPropertiesDialogDo(context,
  2430.                                             XFE_EDITOR_PROPERTIES_CHARACTER);
  2431.             else if (XP_STRCASECMP(av[0], "paragraph") == 0)
  2432.                 fe_EditorPropertiesDialogDo(context,
  2433.                                             XFE_EDITOR_PROPERTIES_PARAGRAPH);
  2434.             else if (XP_STRCASECMP(av[0], "link") == 0)
  2435.                 fe_EditorPropertiesDialogDo(context,
  2436.                                             XFE_EDITOR_PROPERTIES_LINK);
  2437.             else if (XP_STRCASECMP(av[0], "target") == 0)
  2438.                 fe_EditorTargetPropertiesDialogDo(context);
  2439.             else if (XP_STRCASECMP(av[0], "image") == 0)
  2440.                 fe_EditorPropertiesDialogDo(context,
  2441.                                             XFE_EDITOR_PROPERTIES_IMAGE);
  2442.             else if (XP_STRCASECMP(av[0], "hrule") == 0)
  2443.                 fe_EditorHorizontalRulePropertiesDialogDo(context);
  2444.             else if (XP_STRCASECMP(av[0], "tag") == 0)
  2445.                 fe_EditorHtmlPropertiesDialogDo(context);
  2446.             else if (XP_STRCASECMP(av[0], "document") == 0)
  2447.                 fe_EditorDocumentPropertiesDialogDo(context,
  2448.                             XFE_EDITOR_DOCUMENT_PROPERTIES_APPEARANCE);
  2449.             else if (XP_STRCASECMP(av[0], "table") == 0)
  2450.                 fe_EditorTablePropertiesDialogDo(context,
  2451.                                                  XFE_EDITOR_PROPERTIES_TABLE);
  2452.             else if (XP_STRCASECMP(av[0], "table-insert") == 0)
  2453.                 fe_EditorTableCreateDialogDo(context);
  2454.             else if (XP_STRCASECMP(av[0], "color") == 0)
  2455.                 fe_EditorSetColorsDialogDo(context);
  2456.             else if (XP_STRCASECMP(av[0], "publish") == 0)
  2457.                 fe_EditorPublishDialogDo(context);
  2458.             else
  2459.                 nerrors++;
  2460.         } else {
  2461.             nerrors++;
  2462.         }
  2463.  
  2464.         if (nerrors != 0)
  2465.             FE_SYNTAX_ERROR();
  2466.     };
  2467. };
  2468.  
  2469. static void
  2470. fe_get_selected_text_rect(MWContext* context,
  2471.               LO_TextStruct* text,
  2472.               int32*         rect_x,
  2473.               int32*         rect_y,
  2474.               int32*         rect_width,
  2475.               int32*         rect_height)
  2476. {
  2477.     PA_Block    text_save = text->text;
  2478.     int         len_save = text->text_len;
  2479.     LO_TextInfo info;
  2480.     
  2481.     text->text_len = text->sel_start;
  2482.     XFE_GetTextInfo(context, text, &info);
  2483.  
  2484.     *rect_x = text->x + text->x_offset + info.max_width;
  2485.     *rect_y = text->y + text->y_offset;
  2486.  
  2487.     text->text = (PA_Block)((char*)text->text + text->sel_start);
  2488.     text->text_len = text->sel_end - text->sel_start;
  2489.     
  2490.     XFE_GetTextInfo(context, text, &info);
  2491.  
  2492.     *rect_width = info.max_width;
  2493.     *rect_height = info.ascent + info.descent;
  2494.  
  2495.     text->text = text_save;
  2496.     text->text_len = len_save;
  2497. }
  2498.  
  2499. static Boolean
  2500. fe_editor_selection_contains_point(MWContext* context, int32 x, int32 y)
  2501. {
  2502.     int32 start_selection;
  2503.     int32 end_selection;
  2504.     LO_Element* start_element = NULL;
  2505.     LO_Element* end_element = NULL;
  2506.     LO_Element* lo_element;
  2507.     int32 rect_x;
  2508.     int32 rect_y;
  2509.     int32 rect_width;
  2510.     int32 rect_height;
  2511.     CL_Layer *layer;
  2512.  
  2513.     if (!EDT_IsSelected(context))
  2514.         return FALSE;
  2515.  
  2516.     LO_GetSelectionEndpoints(context,
  2517.                              &start_element,
  2518.                              &end_element,
  2519.                              &start_selection,
  2520.                              &end_selection,
  2521.                              &layer);
  2522.  
  2523.     if (start_element == NULL)
  2524.         return FALSE;
  2525.  
  2526.     for (lo_element = start_element;
  2527.          lo_element != NULL;
  2528.          lo_element = ((LO_Any *)lo_element)->next) {
  2529.  
  2530.         if (lo_element->type == LO_TEXT &&
  2531.             (lo_element == start_element || lo_element == end_element)) {
  2532.             LO_TextStruct* text = (LO_TextStruct*)lo_element;
  2533.  
  2534.             if (text->text == NULL) {
  2535.                 if (text->prev != NULL && text->prev->type == LO_TEXT) {
  2536.                     text = (LO_TextStruct*)text->prev;
  2537.                 } else {
  2538.                     text = (LO_TextStruct*)text->next;
  2539.                 }
  2540.             }
  2541.         
  2542.             if (text->text == NULL)
  2543.                 continue;
  2544.         
  2545.             fe_get_selected_text_rect(context, text,
  2546.                                       &rect_x,
  2547.                                       &rect_y,
  2548.                                       &rect_width,
  2549.                                       &rect_height);
  2550.         
  2551.         } else if (lo_element->type == LO_LINEFEED) {
  2552.             continue;
  2553.         
  2554.         } else {
  2555.             LO_Any* lo_any = (LO_Any*)lo_element;
  2556.             rect_x = lo_any->x + lo_any->x_offset;
  2557.             rect_y = lo_any->y + lo_any->y_offset;
  2558.             rect_width = lo_any->width;
  2559.             rect_height = lo_any->height;
  2560.         }
  2561.     
  2562.         if (x > rect_x && y > rect_y &&
  2563.             x < (rect_x + rect_width) && y < (rect_y + rect_height))
  2564.             return TRUE;
  2565.  
  2566.         if (lo_element == end_element)
  2567.             break;
  2568.     }
  2569.  
  2570.     return FALSE;
  2571. }
  2572.  
  2573. class PopupCommand : public XFE_EditorViewCommand
  2574. {
  2575. public:
  2576.     PopupCommand() : XFE_EditorViewCommand(xfeCmdShowPopup) {};
  2577.     
  2578.     void reallyDoCommand(XFE_View* view, XFE_CommandInfo* info);
  2579. };
  2580.  
  2581. void
  2582. PopupCommand::reallyDoCommand(XFE_View* v_view, XFE_CommandInfo* info)
  2583. {    
  2584.     XFE_EditorView* view = (XFE_EditorView*)v_view;
  2585.  
  2586.     if (info != NULL) {
  2587.         MWContext* context = view->getContext();
  2588.         unsigned long x;
  2589.         unsigned long y;
  2590.         XFE_PopupMenu* popup;
  2591.         
  2592.         fe_EventLOCoords(context, info->event, &x, &y);
  2593.         
  2594.         if (!fe_editor_selection_contains_point(context, x, y))
  2595.             EDT_SelectObject(context, x, y);
  2596.         
  2597.         popup = fe_EditorNewPopupMenu((XFE_Frame*)view->getToplevel(),
  2598.                                       info->widget);
  2599.  
  2600.         view->setPopupMenu(popup);
  2601.         popup = view->getPopupMenu();
  2602.  
  2603.         if (popup != NULL) {
  2604.             popup->position(info->event);
  2605.             popup->show();
  2606.         }
  2607.     }
  2608. }
  2609.  
  2610. static char*
  2611. get_base_url(MWContext* context, char* rel_url)
  2612. {
  2613.     History_entry* hist_ent;
  2614.  
  2615.     if (context != NULL && rel_url != NULL) {
  2616.         hist_ent = SHIST_GetCurrent(&context->hist);
  2617.         if (hist_ent != NULL) {
  2618.             return NET_MakeAbsoluteURL(hist_ent->address, rel_url);
  2619.             /*caller must XP_FREE()*/
  2620.         }
  2621.     }
  2622.     return NULL;
  2623. }
  2624.  
  2625. static char label_buf[256];
  2626.  
  2627. class BrowseLinkCommand : public XFE_EditorViewCommand
  2628. {
  2629. public:
  2630.     BrowseLinkCommand() : XFE_EditorViewCommand(xfeCmdOpenLinkNew) {};
  2631.     
  2632.     void reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  2633.         MWContext* context = view->getContext();
  2634.         EDT_HREFData* href_data = EDT_GetHREFData(context);
  2635.         
  2636.         if (href_data != NULL) {
  2637.             if (href_data->pURL != NULL) {
  2638.                 char* abs = get_base_url(context, href_data->pURL);
  2639.                 if (abs != NULL) {
  2640.                     URL_Struct* url = NET_CreateURLStruct(abs,NET_DONT_RELOAD);
  2641.                     FE_GetURL(context, url);
  2642.                     XP_FREE(abs);
  2643.                 }
  2644.             }
  2645.             EDT_FreeHREFData(href_data);
  2646.         }
  2647.     }
  2648.     char*   getLabel(XFE_View* view, XFE_CommandInfo* info) {
  2649.         char* s = NULL;
  2650.         char* link = NULL;
  2651.         char* res_name = NULL;
  2652.  
  2653.         MWContext* context = view->getContext();
  2654.         EDT_HREFData* href_data = EDT_GetHREFData(context);
  2655.         
  2656.         if (href_data != NULL) {
  2657.             if (href_data->pURL != NULL) {
  2658.                 link = XP_STRRCHR(href_data->pURL, '/');
  2659.                 if (link != NULL)
  2660.                     link++;
  2661.                 else
  2662.                     link = href_data->pURL;
  2663.                 res_name = "browseToLink";
  2664.             }
  2665.         }
  2666.  
  2667.         if (info != NULL && res_name != NULL && link != NULL) {
  2668.             s = XfeSubResourceGetStringValue(info->widget,
  2669.                                              res_name, 
  2670.                                              XfeClassNameForWidget(info->widget),
  2671.                                              XmNlabelString, 
  2672.                                              XmCLabelString,
  2673.                                              NULL);
  2674.             if (s != NULL)
  2675.                 XP_SPRINTF(label_buf, s, link);
  2676.  
  2677.             s = label_buf;
  2678.         }
  2679.  
  2680.         if (href_data != NULL)
  2681.             EDT_FreeHREFData(href_data);
  2682.  
  2683.         return s;
  2684.     };
  2685. };
  2686.  
  2687. class EditLinkCommand : public XFE_EditorViewCommand
  2688. {
  2689. public:
  2690.     EditLinkCommand() : XFE_EditorViewCommand(xfeCmdOpenLinkEdit) {};
  2691.     
  2692.     void reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  2693.         MWContext* context = view->getContext();
  2694.         EDT_HREFData* href_data = EDT_GetHREFData(context);
  2695.     
  2696.         if (href_data != NULL) {
  2697.             if (href_data->pURL != NULL) {
  2698.                 char* abs = get_base_url(context, href_data->pURL);
  2699.                 if (abs != NULL) {
  2700.                     fe_EditorNew(context, 0, 0, abs);
  2701.                     XP_FREE(abs);
  2702.                 }
  2703.             }
  2704.             EDT_FreeHREFData(href_data);
  2705.         }
  2706.     }
  2707. };
  2708.  
  2709. class BookmarkLinkCommand : public XFE_EditorViewCommand
  2710. {
  2711. public:
  2712.     BookmarkLinkCommand() : XFE_EditorViewCommand(xfeCmdAddLinkBookmark) {};
  2713.     
  2714.     void reallyDoCommand(XFE_View* view, XFE_CommandInfo*) {
  2715.         MWContext* context = view->getContext();
  2716.         EDT_HREFData* href_data = EDT_GetHREFData(context);
  2717.     
  2718.         if (href_data != NULL) {
  2719.             if (href_data->pURL != NULL) {
  2720.                 fe_AddToBookmark(context, 0,
  2721.                      NET_CreateURLStruct(href_data->pURL, NET_DONT_RELOAD), 0);
  2722.             }
  2723.             EDT_FreeHREFData(href_data);
  2724.         }
  2725.     }
  2726. };
  2727.  
  2728. class CopyLinkCommand : public XFE_EditorViewCommand
  2729. {
  2730. public:
  2731.     CopyLinkCommand() : XFE_EditorViewCommand(xfeCmdCopyLink) {};
  2732.     
  2733.     void reallyDoCommand(XFE_View* view, XFE_CommandInfo* info) {
  2734.         if (info != NULL) {
  2735.             MWContext* context = view->getContext();
  2736.             EDT_HREFData* href_data = EDT_GetHREFData(context);
  2737.             
  2738.             Time now = fe_GetTimeFromEvent(info->event);
  2739.             
  2740.             if (href_data != NULL) {
  2741.                 if (href_data->pURL != NULL) {
  2742.                     fe_EditorCopyToClipboard(context, href_data->pURL, now);
  2743.                 }
  2744.                 EDT_FreeHREFData(href_data);
  2745.             }
  2746.         }
  2747.     }
  2748. };
  2749.  
  2750. //    END OF COMMAND DEFINES
  2751.  
  2752. static XFE_CommandList* my_commands = 0;
  2753.  
  2754. XFE_EditorView::XFE_EditorView(XFE_Component *toplevel_component,
  2755.                    Widget parent,
  2756.                    XFE_View *parent_view,
  2757.                    MWContext *context) 
  2758.   : XFE_HTMLView(toplevel_component, parent, parent_view, context)
  2759. {
  2760.     m_update_timer = 0;
  2761.  
  2762.     //
  2763.     // Register editor drop site
  2764.     //
  2765.     _dropSite=new XFE_EditorDrop(getBaseWidget(),this);
  2766.     _dropSite->enable();
  2767.  
  2768.     if (my_commands != 0)
  2769.         return;
  2770.  
  2771.     registerCommand(my_commands, new BrowseLinkCommand);
  2772.     registerCommand(my_commands, new EditLinkCommand);
  2773.     registerCommand(my_commands, new BookmarkLinkCommand);
  2774.     registerCommand(my_commands, new CopyLinkCommand);
  2775.     registerCommand(my_commands, new PopupCommand);
  2776.     registerCommand(my_commands, new UndoCommand);
  2777.     registerCommand(my_commands, new RedoCommand);
  2778.     registerCommand(my_commands, new CutCommand);
  2779.     registerCommand(my_commands, new CopyCommand);
  2780.     registerCommand(my_commands, new PasteCommand);
  2781.     registerCommand(my_commands, new DeleteCommand);
  2782.     registerCommand(my_commands, new SpellCommand);
  2783.     registerCommand(my_commands, new SaveCommand);
  2784.     registerCommand(my_commands, new SaveAsCommand);
  2785.     registerCommand(my_commands, new PublishCommand);
  2786.     registerCommand(my_commands, new DeleteTableCommand);
  2787.     registerCommand(my_commands, new DeleteTableCellCommand);
  2788.     registerCommand(my_commands, new DeleteTableRowCommand);
  2789.     registerCommand(my_commands, new DeleteTableColumnCommand);
  2790.     registerCommand(my_commands, new RemoveLinkCommand);
  2791.     registerCommand(my_commands, new SelectAllCommand);
  2792.     registerCommand(my_commands, new FindCommand);
  2793.     registerCommand(my_commands, new FindAgainCommand);
  2794.     registerCommand(my_commands, new ToggleTableBordersCommand);
  2795.     registerCommand(my_commands, new ToggleParagraphMarksCommand);
  2796.     registerCommand(my_commands, new ReloadCommand);
  2797.     registerCommand(my_commands, new RefreshCommand);
  2798.     registerCommand(my_commands, new InsertLinkCommand);
  2799.     registerCommand(my_commands, new InsertTargetCommand);
  2800.     registerCommand(my_commands, new InsertImageCommand);
  2801.     registerCommand(my_commands, new InsertHorizontalLineCommand);
  2802.     registerCommand(my_commands, new InsertBulletedListCommand);
  2803.     registerCommand(my_commands, new InsertNumberedListCommand);
  2804.     registerCommand(my_commands, new InsertTableCommand);
  2805.     registerCommand(my_commands, new InsertTableRowCommand);
  2806.     registerCommand(my_commands, new InsertTableColumnCommand);
  2807.     registerCommand(my_commands, new InsertTableCellCommand);
  2808.     registerCommand(my_commands, new InsertHtmlCommand);
  2809.     registerCommand(my_commands, new InsertLineBreakCommand);
  2810.     registerCommand(my_commands, new InsertBreakBelowImageCommand);
  2811.     registerCommand(my_commands, new InsertNonBreakingSpaceCommand);
  2812.     registerCommand(my_commands, new SetFontSizeCommand);
  2813.     registerCommand(my_commands, new SetFontFaceCommand);
  2814.     registerCommand(my_commands, new SetFontColorCommand);
  2815.     registerCommand(my_commands, new SetParagraphStyleCommand);
  2816.     registerCommand(my_commands, new SetListStyleCommand);
  2817.     registerCommand(my_commands, new SetAlignStyleCommand);
  2818.     registerCommand(my_commands, new SetCharacterStyleCommand);
  2819.     registerCommand(my_commands, new ToggleCharacterStyleCommand);
  2820.     registerCommand(my_commands, new ClearAllStylesCommand);
  2821.     registerCommand(my_commands, new IndentCommand);
  2822.     registerCommand(my_commands, new OutdentCommand);
  2823.     registerCommand(my_commands, new SetObjectPropertiesCommand);
  2824.     registerCommand(my_commands, new SetPagePropertiesCommand);
  2825.     registerCommand(my_commands, new SetTablePropertiesCommand);
  2826. #ifndef NO_SECURITY
  2827.     registerCommand(my_commands, new SetEncryptedCommand);
  2828. #endif
  2829.     registerCommand(my_commands, new SetCharacterColorCommand);
  2830.     registerCommand(my_commands, new BrowsePageCommand);
  2831.     registerCommand(my_commands, new EditSourceCommand);
  2832.     registerCommand(my_commands, new ViewSourceCommand);
  2833.     registerCommand(my_commands, new EditorObjectIsCommand);
  2834.     registerCommand(my_commands, new DialogCommand);
  2835.     registerCommand(my_commands, new TabCommand);
  2836.  
  2837.     //    non-paramaterized font size commands.
  2838.     registerCommand(my_commands, new SetFontSizeMinusTwoCommand);
  2839.     registerCommand(my_commands, new SetFontSizeMinusOneCommand);
  2840.     registerCommand(my_commands, new SetFontSizeZeroCommand);
  2841.     registerCommand(my_commands, new SetFontSizePlusOneCommand);
  2842.     registerCommand(my_commands, new SetFontSizePlusTwoCommand);
  2843.     registerCommand(my_commands, new SetFontSizePlusThreeCommand);
  2844.     registerCommand(my_commands, new SetFontSizePlusFourCommand);
  2845.     registerCommand(my_commands, new SetParagraphStyleNormalCommand);
  2846.     registerCommand(my_commands, new SetParagraphStyleHeadingOneCommand);
  2847.     registerCommand(my_commands, new SetParagraphStyleHeadingTwoCommand);
  2848.     registerCommand(my_commands, new SetParagraphStyleHeadingThreeCommand);
  2849.     registerCommand(my_commands, new SetParagraphStyleHeadingFourCommand);
  2850.     registerCommand(my_commands, new SetParagraphStyleHeadingFiveCommand);
  2851.     registerCommand(my_commands, new SetParagraphStyleHeadingSixCommand);
  2852.  
  2853.     registerCommand(my_commands, new SetParagraphStyleAddressCommand);
  2854.     registerCommand(my_commands, new SetParagraphStyleFormattedCommand);
  2855.     registerCommand(my_commands, new SetParagraphStyleTitleCommand);
  2856.     registerCommand(my_commands, new SetParagraphStyleTextCommand);
  2857.     registerCommand(my_commands, new SetParagraphStyleBlockQuoteCommand);
  2858.  
  2859.     registerCommand(my_commands, new SetListStyleNoneCommand);
  2860.     registerCommand(my_commands, new SetListStyleBulletedCommand);
  2861.     registerCommand(my_commands, new SetListStyleNumberedCommand);
  2862.  
  2863.     registerCommand(my_commands, new SetAlignStyleLeftCommand);
  2864.     registerCommand(my_commands, new SetAlignStyleCenterCommand);
  2865.     registerCommand(my_commands, new SetAlignStyleRightCommand);
  2866.  
  2867.     registerCommand(my_commands, new ToggleCharacterStyleBoldCommand);
  2868.     registerCommand(my_commands, new ToggleCharacterStyleItalicCommand);
  2869.     registerCommand(my_commands, new ToggleCharacterStyleUnderlineCommand);
  2870.     registerCommand(my_commands, new ToggleCharacterStyleFixedCommand);
  2871.     registerCommand(my_commands, new ToggleCharacterStyleSuperscriptCommand);
  2872.     registerCommand(my_commands, new ToggleCharacterStyleSubscriptCommand);
  2873.     registerCommand(my_commands, new ToggleCharacterStyleStrikethroughCommand);
  2874.     registerCommand(my_commands, new ToggleCharacterStyleBlinkCommand);
  2875.  
  2876.     //
  2877.     //    Register Java Plugin Commands.
  2878.     //
  2879.     int32 ncategories = EDT_NumberOfPluginCategories();
  2880.  
  2881.     for (int32 nc = 0; nc < ncategories; nc++) {
  2882.  
  2883.         int32 nplugins = EDT_NumberOfPlugins(nc);
  2884.  
  2885.         for (int32 np = 0; np < nplugins; np++) {
  2886.             char buf[64];
  2887.             char* name;
  2888.  
  2889.             sprintf(buf, "javaPlugin_%d_%d", nc, np);
  2890.             name = Command::intern(buf);
  2891.  
  2892.             registerCommand(my_commands, new JavaPluginCommand(name, nc, np));
  2893.         }
  2894.     }
  2895.  
  2896.     //
  2897.     //    Insert these last, so they are at the head of the command
  2898.     //    list, and will get found quickly.
  2899.     //
  2900.     registerCommand(my_commands, new InsertReturnCommand);
  2901.     registerCommand(my_commands, new SelectCommand);
  2902.     registerCommand(my_commands, new MoveCommand);
  2903.     registerCommand(my_commands, new KeyInsertCommand);
  2904. }
  2905.  
  2906. XFE_EditorView::~XFE_EditorView()
  2907. {
  2908.     if (_dropSite) {
  2909.         delete _dropSite;
  2910.         _dropSite=NULL;
  2911.     }
  2912.     if (m_update_timer != 0) {
  2913.         XtRemoveTimeOut(m_update_timer);
  2914.         m_update_timer = 0;
  2915.     }
  2916. }
  2917.  
  2918. char*
  2919. XFE_EditorView::getPlainText()
  2920. {
  2921.   // This method suppose to get the text message in the widget
  2922.   // and return in a char string block
  2923.   return NULL;
  2924. }
  2925.  
  2926. #ifdef DEBUG_editor
  2927. #define TRACE(x) printf x
  2928. #else
  2929. #define TRACE(x)
  2930. #endif
  2931.  
  2932. XFE_Command*
  2933. XFE_EditorView::getCommand(CommandType cmd)
  2934. {
  2935.     XFE_Command* command = findCommand(my_commands, cmd);
  2936.  
  2937.     if (command != NULL)
  2938.         return command;
  2939.     else
  2940.         return XFE_HTMLView::getCommand(cmd);
  2941. }
  2942.  
  2943. void 
  2944. XFE_EditorView::insertMessageCompositionText(const char* text, 
  2945.                          XP_Bool leaveCursorBeginning, XP_Bool isHTML)
  2946. {
  2947. #ifdef DEBUG_editor
  2948.     fprintf(stderr, "ping::[ insertMessageCompositionText ]\n");
  2949. #endif
  2950.  
  2951.     if (m_contextData) {
  2952.         Boolean  noTagsP = False;
  2953.         Boolean  inDraft = False;
  2954.  
  2955.         ED_BufferOffset ins = -1;
  2956.  
  2957.         if ( leaveCursorBeginning ){
  2958.             ins = EDT_GetInsertPointOffset( m_contextData );
  2959.         }
  2960.  
  2961.         if (isHTML) {
  2962.             //
  2963.             // NOTE:  let's try to see if they really have any HTML tags 
  2964.             //        in the text they've given us... [ poor man's parser ]
  2965.             //
  2966.             char *xtop = XP_STRSTR( text, "<HTML>" );
  2967.             
  2968.             int   s1 = XP_STRLEN( text );
  2969.             int   s2 = 0;
  2970.             int   n  = 0;
  2971.  
  2972. #ifdef DEBUG_editor
  2973.             fprintf(stderr, "  paste::[ %d ]\n", s1);
  2974. #endif
  2975.  
  2976.             if ( xtop ) {
  2977.                 s2 = XP_STRLEN( xtop );
  2978.                 n  = s1 - s2;
  2979.             }
  2980.  
  2981.             if ( xtop && ( n < 2 )) {
  2982.                 inDraft = True;
  2983.             }
  2984.             else {
  2985.                 s2 = 0;
  2986.                 n  = 0;
  2987.  
  2988.                 if (XP_STRCASESTR(text, "</A>")   ||
  2989.                     XP_STRCASESTR(text, "<PRE>")  ||
  2990.                     XP_STRCASESTR(text, "<HR")    ||
  2991.                     XP_STRCASESTR(text, "<IMG")   ||
  2992.                     XP_STRCASESTR(text, "<TABLE")
  2993.                     ) {
  2994.                     noTagsP = False;
  2995.                 }
  2996.                 else {
  2997. #ifdef DEBUG_editor
  2998.                     fprintf(stderr, 
  2999.                             "WARNING... [ looks like plaintext to me ]\n");
  3000. #endif            
  3001.                     noTagsP = True;
  3002.                 }
  3003.             }
  3004.  
  3005.             EDT_PasteQuoteBegin( m_contextData, isHTML );
  3006.  
  3007.             char *xsig = 0;
  3008.             char *xtra = 0;
  3009.  
  3010.             if (inDraft) {
  3011.                 // NOTE:  we're loading a draft message, don't mess with it!!!
  3012.                 //
  3013.                 xtra = 0;
  3014.                 xsig = 0;
  3015.  
  3016.                 EDT_PasteQuote( m_contextData, (char *) text );
  3017.             }
  3018.             else {
  3019.                 // NOTE:  try to figure out if we've got a signature...
  3020.                 //
  3021.                 if (s1 > 2) {
  3022.                     xsig = XP_STRSTR( text, "-- " );
  3023.                     
  3024.                     if (xsig) {
  3025.                         s2 = XP_STRLEN( xsig );
  3026.                         n  = s1 - s2;
  3027.                     }
  3028.                 }
  3029.  
  3030.                 if ( n > 1 ) {
  3031.                     xtra = (char *) XP_ALLOC( n + 1 );
  3032.  
  3033.                     XP_STRNCPY_SAFE(xtra, text, n );
  3034. #ifdef DEBUG_editor
  3035.                     fprintf(stderr, 
  3036.                             "WARNING... [ hacking pre-signature string ]\n");
  3037. #endif
  3038.                 }
  3039.                 else {
  3040.                     xtra = 0;
  3041.  
  3042.                     if ( n == 0 ) {
  3043.                         xsig = (char *) text;
  3044.                     }
  3045.                 }
  3046.  
  3047.                 if ( xtra ) {
  3048.                     EDT_PasteQuote( m_contextData, (char *) xtra );
  3049.                 }
  3050.  
  3051.                 EDT_PasteQuote( m_contextData, "<BR>");
  3052. #ifdef DEBUG_editor
  3053.                 fprintf(stderr, 
  3054.                         "WARNING... [ insert pre-sig break ]\n");
  3055. #endif
  3056.                 if (noTagsP)  
  3057.                     EDT_PasteQuote( m_contextData, "<PRE>");
  3058.  
  3059.                 EDT_PasteQuote( m_contextData, (char *) xsig );
  3060.  
  3061.                 if (noTagsP)  
  3062.                     EDT_PasteQuote( m_contextData, "</PRE>" );
  3063.  
  3064.                 EDT_PasteQuote( m_contextData, "<BR>" );
  3065. #ifdef DEBUG_editor
  3066.                 fprintf(stderr, 
  3067.                         "WARNING... [ insert post-sig break ]\n");
  3068. #endif
  3069.             }
  3070.  
  3071.             EDT_PasteQuoteEnd( m_contextData );
  3072.  
  3073.             if ( xtra ) {
  3074.                 XP_FREE( xtra );
  3075.             }
  3076.         }
  3077.         else {
  3078.             EDT_PasteText( m_contextData, (char *) text );
  3079.         }
  3080.  
  3081.         if ( leaveCursorBeginning && ins != -1 ) {
  3082.             EDT_SetInsertPointToOffset( m_contextData, ins, 0 );
  3083.         }
  3084.  
  3085.     }
  3086. }
  3087.  
  3088. void 
  3089. XFE_EditorView::getMessageBody(char **pBody, uint32 *body_size, 
  3090.                    MSG_FontCode** /*font_changes*/)
  3091. {
  3092. #ifdef DEBUG_editor
  3093.    fprintf(stderr, "ping::[ getMessageBody ]\n");
  3094. #endif
  3095.  
  3096.    *pBody = NULL;
  3097.    *body_size = 0;
  3098.  
  3099.    EDT_SaveToBuffer(m_contextData, pBody);
  3100.  
  3101.    if ( !*pBody){
  3102.      // oops...
  3103.    }
  3104.    else {
  3105.      size_t lsize;
  3106.      lsize = strlen(*pBody);
  3107.      *body_size = lsize;
  3108.    }
  3109. }
  3110.  
  3111. void 
  3112. XFE_EditorView::doneWithMessageBody(char* /*pBody*/)
  3113. {
  3114. #ifdef DEBUG_editor
  3115.    fprintf(stderr, "ping::[ doneWithMessageBody ]\n");
  3116. #endif
  3117. }
  3118.  
  3119. void
  3120. XFE_EditorView::DocEncoding (XFE_NotificationCenter *, void *, void *callData)
  3121. {
  3122.     int new_doc_csid = (int)callData;
  3123.  
  3124. #ifdef DEBUG_editor
  3125.     fprintf(stderr, "DocEncoding::[ %d ]\n", new_doc_csid);
  3126. #endif
  3127.     EDT_SetEncoding(m_contextData, new_doc_csid);
  3128. }
  3129.  
  3130. Boolean
  3131. XFE_EditorView::isModified()
  3132. {
  3133.     return EDT_DirtyFlag(m_contextData);
  3134. }
  3135.  
  3136. void
  3137. XFE_EditorView::updateChromeTimeout(XtPointer closure, XtIntervalId*)
  3138. {
  3139.     XFE_EditorView* view = (XFE_EditorView*)closure;
  3140.  
  3141.     //    do this before you do anything else
  3142.     view->m_update_timer = 0;
  3143.  
  3144.     //    tell the frame to update.
  3145.     XFE_Component* top = view->getToplevel();
  3146.     top->notifyInterested(XFE_View::chromeNeedsUpdating);
  3147. }
  3148.  
  3149. void
  3150. XFE_EditorView::updateChrome()
  3151. {
  3152.     Cardinal delay = fe_globalData.editor_update_delay;
  3153.     
  3154.     //
  3155.     //    If there is an outstanding timer, reset, and start again.
  3156.     //    This way we always wait until we just not doing anything
  3157.     //    to redraw the toolbars. This should probably be a workproc
  3158.     //    thing, we don't have Xt WorkProcs and right now, I don't
  3159.     //    want to mess with fe_EventLoop() to make them work.
  3160.     //
  3161.     if (m_update_timer != 0) {
  3162.         XtRemoveTimeOut(m_update_timer);
  3163.         m_update_timer = 0;
  3164.     }
  3165.  
  3166.     if (delay != 0) {
  3167.         m_update_timer = XtAppAddTimeOut(fe_XtAppContext,
  3168.                                          delay,
  3169.                                          updateChromeTimeout,
  3170.                                          this);
  3171.     } else {
  3172.         updateChromeTimeout(this, 0);
  3173.     }
  3174. }
  3175.  
  3176. XFE_View*
  3177. XFE_EditorView::getCommandView(XFE_Command*)
  3178. {
  3179.     return this;
  3180. }
  3181.