home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / xfe / src / EditorFrame.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  37.0 KB  |  1,373 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.    EditorFrame.cpp -- class definition for the editor frame class
  20.    Created: Richard Hess <rhess@netscape.com>, 11-Nov-96
  21.  */
  22.  
  23.  
  24.  
  25. #include "EditorFrame.h"
  26. #include "EditorView.h"
  27. #include "Command.h"
  28. #include "ViewGlue.h" // remove with fe_HackEditorNotifyToolbarUpdated()
  29. #include "PrefsDialog.h"
  30. #include "xpassert.h"
  31.  
  32. #include "DtWidgets/ComboBox.h"
  33.  
  34. #include "xeditor.h"
  35. #include "edt.h"
  36. #include "EditRecentMenu.h"
  37.  
  38. /* for XP_GetString() */
  39. #include <xpgetstr.h>
  40. extern int XFE_DISABLED_BY_ADMIN;
  41. extern int XFE_EDITOR_ALERT_ABOUT_DOCUMENT;
  42.  
  43. #ifdef DEBUG_spence
  44. #define D(x) x
  45. #else
  46. #define D(x)
  47. #endif
  48.  
  49. extern "C"   void xfe2_EditorInit(MWContext* context);
  50. extern "C"   void fe_set_scrolled_default_size(MWContext *context);
  51. extern "C"   void fe_HackTranslations (MWContext *, Widget);
  52.  
  53. MenuSpec XFE_EditorFrame::file_menu_spec[] = {
  54.   { "newSubmenu",        CASCADEBUTTON,
  55.     (MenuSpec*)&XFE_Frame::new_menu_spec },
  56.   { xfeCmdOpenPage,        PUSHBUTTON },
  57.   { "recentSubmenu",    DYNA_CASCADEBUTTON, 
  58.     NULL, NULL, False, NULL,
  59.     XFE_EditRecentMenu::generate 
  60.   },
  61.   MENU_SEPARATOR,
  62.   { xfeCmdSave,         PUSHBUTTON },
  63.   { xfeCmdSaveAs,        PUSHBUTTON },
  64.   { xfeCmdPublish,      PUSHBUTTON },
  65.   MENU_SEPARATOR,
  66.   { xfeCmdSendPage,        PUSHBUTTON },
  67.   { xfeCmdBrowsePage,    PUSHBUTTON },
  68.   MENU_SEPARATOR,
  69.   //{ xfeCmdPrintSetup,    PUSHBUTTON },
  70.   //{ xfeCmdPrintPreview,    PUSHBUTTON },
  71.   { xfeCmdPrint,        PUSHBUTTON },
  72.   MENU_SEPARATOR,
  73.   { xfeCmdClose,        PUSHBUTTON },
  74.   { xfeCmdExit,            PUSHBUTTON },
  75.   { NULL }
  76. };
  77.  
  78. MenuSpec XFE_EditorFrame::delete_table_menu_spec[] = {
  79.     { xfeCmdDeleteTable,       PUSHBUTTON },
  80.     { xfeCmdDeleteTableRow,    PUSHBUTTON },
  81.     { xfeCmdDeleteTableColumn, PUSHBUTTON },
  82.     { xfeCmdDeleteTableCell,   PUSHBUTTON },
  83.     { NULL }
  84. };
  85.  
  86. MenuSpec XFE_EditorFrame::edit_menu_spec[] = {
  87.   { xfeCmdUndo,            PUSHBUTTON },
  88.   { xfeCmdRedo,            PUSHBUTTON },
  89.   MENU_SEPARATOR,
  90.   { xfeCmdCut,            PUSHBUTTON },
  91.   { xfeCmdCopy,            PUSHBUTTON },
  92.   { xfeCmdPaste,        PUSHBUTTON },
  93.   { xfeCmdDeleteItem,    PUSHBUTTON },
  94.   MENU_SEPARATOR,
  95.   { "deleteTableMenu",    CASCADEBUTTON,
  96.     (MenuSpec*)&delete_table_menu_spec },
  97.   { xfeCmdRemoveLink,    PUSHBUTTON },
  98.   MENU_SEPARATOR,
  99.   { xfeCmdSelectAll,    PUSHBUTTON },
  100.   { xfeCmdSelectTable,    PUSHBUTTON },
  101.   MENU_SEPARATOR,
  102.   { xfeCmdFindInObject,    PUSHBUTTON },
  103.   { xfeCmdFindAgain,    PUSHBUTTON },
  104.   { xfeCmdSearchAddress,    PUSHBUTTON },
  105.   MENU_SEPARATOR,
  106.   { xfeCmdEditPageSource,PUSHBUTTON },
  107.   MENU_SEPARATOR,
  108.   { xfeCmdEditPreferences,PUSHBUTTON },
  109.   { NULL }
  110. };
  111.  
  112. MenuSpec XFE_EditorFrame::view_menu_spec[] = {
  113.   { xfeCmdToggleNavigationToolbar, PUSHBUTTON },
  114.   { xfeCmdToggleFormatToolbar, PUSHBUTTON },
  115.   MENU_SEPARATOR,
  116.   { xfeCmdToggleParagraphMarks, PUSHBUTTON }, /* with toggling label */
  117.   MENU_SEPARATOR,
  118.   { xfeCmdReload,            PUSHBUTTON },
  119.   { xfeCmdShowImages,        PUSHBUTTON },
  120.   { xfeCmdRefresh,            PUSHBUTTON },
  121.   { xfeCmdStopLoading,        PUSHBUTTON },
  122.   //{ xfeCmdStopAnimations,    PUSHBUTTON },
  123.   MENU_SEPARATOR,
  124.   { xfeCmdViewPageSource,    PUSHBUTTON },
  125.   { xfeCmdViewPageInfo,        PUSHBUTTON },
  126.   //xxxAdd Page Services
  127.   MENU_SEPARATOR,
  128.   { "encodingSubmenu",        CASCADEBUTTON,
  129.     (MenuSpec*)&XFE_Frame::encoding_menu_spec },
  130.   // fix me..
  131.   { NULL }
  132. };
  133.  
  134. static MenuSpec insert_table_menu_spec[] = {
  135.     { xfeCmdInsertTable, PUSHBUTTON },
  136.     { xfeCmdInsertTableRow, PUSHBUTTON },
  137.     { xfeCmdInsertTableColumn, PUSHBUTTON },
  138.     { xfeCmdInsertTableCell, PUSHBUTTON },
  139.     { NULL }
  140. };
  141.  
  142. MenuSpec XFE_EditorFrame::insert_menu_spec[] = {
  143.     { xfeCmdInsertLink, PUSHBUTTON },
  144.     { xfeCmdInsertTarget, PUSHBUTTON },
  145.     { xfeCmdInsertImage, PUSHBUTTON }, 
  146.     { xfeCmdInsertHorizontalLine, PUSHBUTTON },
  147.     { "insertTableMenu",        CASCADEBUTTON,
  148.       (MenuSpec*)&insert_table_menu_spec },
  149.     { xfeCmdInsertHtml, PUSHBUTTON },
  150.     MENU_SEPARATOR,
  151.     { xfeCmdInsertLineBreak, PUSHBUTTON },
  152.     { xfeCmdInsertBreakBelowImage, PUSHBUTTON },
  153.     { NULL }
  154. };
  155.  
  156. MenuSpec XFE_EditorFrame::character_style_menu_spec[] = {
  157.     { xfeCmdToggleCharacterStyleBold, TOGGLEBUTTON },
  158.     { xfeCmdToggleCharacterStyleItalic, TOGGLEBUTTON },
  159.     { xfeCmdToggleCharacterStyleUnderline, TOGGLEBUTTON },
  160.     { xfeCmdToggleCharacterStyleStrikethrough, TOGGLEBUTTON },
  161.     { xfeCmdToggleCharacterStyleSuperscript, TOGGLEBUTTON },
  162.     { xfeCmdToggleCharacterStyleSubscript, TOGGLEBUTTON },
  163.     { xfeCmdToggleCharacterStyleBlink, TOGGLEBUTTON },
  164.     { NULL }
  165. };
  166.  
  167. static char editor_radio_group_name[] = "editorRadiogroup";
  168.  
  169. #define RADIOBUTTON TOGGLEBUTTON, NULL, editor_radio_group_name
  170.  
  171. MenuSpec XFE_EditorFrame::character_size_menu_spec[] = {
  172.     { xfeCmdSetFontSizeMinusTwo, RADIOBUTTON },
  173.     { xfeCmdSetFontSizeMinusOne, RADIOBUTTON },
  174.     { xfeCmdSetFontSizeZero, RADIOBUTTON },
  175.     { xfeCmdSetFontSizePlusOne, RADIOBUTTON },
  176.     { xfeCmdSetFontSizePlusTwo, RADIOBUTTON },
  177.     { xfeCmdSetFontSizePlusThree, RADIOBUTTON },
  178.     { xfeCmdSetFontSizePlusFour, RADIOBUTTON },
  179.     MENU_SEPARATOR,
  180.     { xfeCmdSetFontSize, PUSHBUTTON },
  181.     { NULL }
  182. };
  183.  
  184. MenuSpec XFE_EditorFrame::heading_style_menu_spec[] = {
  185.     { xfeCmdSetParagraphStyleNormal, RADIOBUTTON },
  186.     { xfeCmdSetParagraphStyleHeadingOne, RADIOBUTTON },
  187.     { xfeCmdSetParagraphStyleHeadingTwo, RADIOBUTTON },
  188.     { xfeCmdSetParagraphStyleHeadingThree, RADIOBUTTON },
  189.     { xfeCmdSetParagraphStyleHeadingFour, RADIOBUTTON },
  190.     { xfeCmdSetParagraphStyleHeadingFive, RADIOBUTTON },
  191.     { xfeCmdSetParagraphStyleHeadingSix, RADIOBUTTON },
  192.     { NULL }
  193. };
  194.  
  195. MenuSpec XFE_EditorFrame::paragraph_style_menu_spec[] = {
  196.     { xfeCmdSetParagraphStyleNormal, RADIOBUTTON },
  197.     { xfeCmdSetParagraphStyleAddress, RADIOBUTTON },
  198.     { xfeCmdSetParagraphStyleFormatted, RADIOBUTTON },
  199.     { xfeCmdSetParagraphStyleDescriptionTitle, RADIOBUTTON },
  200.     { xfeCmdSetParagraphStyleDescriptionText, RADIOBUTTON },
  201.     { NULL }
  202. };
  203.  
  204. MenuSpec XFE_EditorFrame::list_style_menu_spec[] = {
  205.     { xfeCmdSetListStyleNone, RADIOBUTTON },
  206.     { xfeCmdSetListStyleBulleted, RADIOBUTTON },
  207.     { xfeCmdSetListStyleNumbered, RADIOBUTTON },
  208.     //xxxAdd Description
  209.     //xxxAdd Menu
  210.     { NULL }
  211. };
  212.  
  213. MenuSpec XFE_EditorFrame::alignment_style_menu_spec[] = {
  214.     { xfeCmdSetAlignmentStyleLeft, RADIOBUTTON },
  215.     { xfeCmdSetAlignmentStyleCenter, RADIOBUTTON },
  216.     { xfeCmdSetAlignmentStyleRight, RADIOBUTTON },
  217.     { NULL }
  218. };
  219.  
  220. MenuSpec XFE_EditorFrame::format_menu_spec[] = {
  221.     { "fontStyleMenu",          CASCADEBUTTON },
  222.     { "characterSizeMenu",      CASCADEBUTTON,
  223.       (MenuSpec*)&XFE_EditorFrame::character_size_menu_spec },
  224.     { "characterStyleMenu",      CASCADEBUTTON,
  225.       (MenuSpec*)&XFE_EditorFrame::character_style_menu_spec },
  226.     { xfeCmdSetCharacterColor,      PUSHBUTTON },
  227.     { xfeCmdClearAllStyles,   PUSHBUTTON },
  228.     MENU_SEPARATOR,
  229.     { "headingStyleMenu",      CASCADEBUTTON,
  230.       (MenuSpec*)&XFE_EditorFrame::heading_style_menu_spec },
  231.     { "paragraphStyleMenu",      CASCADEBUTTON,
  232.       (MenuSpec*)&XFE_EditorFrame::paragraph_style_menu_spec },
  233.     { "listStyleMenu",      CASCADEBUTTON,
  234.       (MenuSpec*)&XFE_EditorFrame::list_style_menu_spec },
  235.     { "alignmentStyleMenu",      CASCADEBUTTON,
  236.       (MenuSpec*)&XFE_EditorFrame::alignment_style_menu_spec },
  237.     MENU_SEPARATOR,
  238.     { xfeCmdIndent,   PUSHBUTTON },
  239.     { xfeCmdOutdent,   PUSHBUTTON },
  240.     MENU_SEPARATOR,
  241.     { xfeCmdSetObjectProperties,   PUSHBUTTON },
  242.     { xfeCmdSetTableProperties,   PUSHBUTTON },
  243.     { xfeCmdSetPageProperties,   PUSHBUTTON },
  244.     { xfeCmdSetEncrypted,   TOGGLEBUTTON },
  245.     { NULL }
  246. };
  247.  
  248. MenuSpec XFE_EditorFrame::tools_menu_spec[] = {
  249.     { xfeCmdSpellCheck,    PUSHBUTTON },
  250.     { NULL }
  251. };
  252.  
  253. MenuSpec XFE_EditorFrame::go_menu_spec[] = {
  254.   { xfeCmdBack,            PUSHBUTTON },
  255.   { xfeCmdForward,        PUSHBUTTON },
  256.   { xfeCmdHome,            PUSHBUTTON },
  257.   // history goes here
  258.   { NULL }
  259. };
  260.  
  261. MenuSpec XFE_EditorFrame::bookmark_menu_spec[] = {
  262.   { xfeCmdAddBookmark,        PUSHBUTTON },
  263.   { xfeCmdFileBookmark,        PUSHBUTTON },
  264.   { xfeCmdEditBookmark,        PUSHBUTTON },
  265.   MENU_SEPARATOR,
  266.   { xfeCmdNetscapeDirectory,    PUSHBUTTON },
  267.   MENU_SEPARATOR,
  268.   { NULL }
  269. };
  270.  
  271. MenuSpec XFE_EditorFrame::menu_bar_spec[] = {
  272.   { xfeMenuFile,     CASCADEBUTTON,
  273.     (MenuSpec*)&XFE_EditorFrame::file_menu_spec },
  274.   { xfeMenuEdit,     CASCADEBUTTON,
  275.     (MenuSpec*)&XFE_EditorFrame::edit_menu_spec },
  276.   { xfeMenuView,     CASCADEBUTTON,
  277.     (MenuSpec*)&XFE_EditorFrame::view_menu_spec },
  278.   { xfeMenuInsert,  CASCADEBUTTON,
  279.     (MenuSpec*)&XFE_EditorFrame::insert_menu_spec },
  280.   { xfeMenuFormat,  CASCADEBUTTON,
  281.     (MenuSpec*)&XFE_EditorFrame::format_menu_spec },
  282.   { xfeMenuTools,     CASCADEBUTTON,
  283.     (MenuSpec*)&XFE_EditorFrame::tools_menu_spec },
  284.   { xfeMenuWindow,     CASCADEBUTTON, (MenuSpec*)&XFE_Frame::window_menu_spec },
  285.   { xfeMenuHelp,     CASCADEBUTTON, (MenuSpec*)&XFE_Frame::help_menu_spec },
  286.   { NULL }
  287. };
  288.  
  289.  
  290. MenuSpec XFE_EditorFrame::new_submenu_spec[] = {
  291.     MENU_PUSHBUTTON(xfeCmdNewBlank),
  292.     MENU_SEPARATOR,
  293.     MENU_PUSHBUTTON(xfeCmdNewTemplate),
  294.     MENU_PUSHBUTTON(xfeCmdNewWizard),
  295.     { NULL }
  296. };
  297.  
  298. MenuSpec XFE_EditorFrame::save_submenu_spec[] = {
  299.     MENU_PUSHBUTTON(xfeCmdSave),
  300.     MENU_PUSHBUTTON(xfeCmdSaveAs),
  301.     { NULL }
  302. };
  303.  
  304. MenuSpec XFE_EditorFrame::publish_submenu_spec[] = {
  305.     MENU_PUSHBUTTON(xfeCmdPublish),
  306.     MENU_PUSHBUTTON(xfeCmdSendPage),
  307.     { NULL }
  308. };
  309.  
  310. static ToolbarSpec editor_file_toolbar_spec[] = {
  311.     { 
  312.         xfeCmdNewBlank,
  313.         CASCADEBUTTON,
  314.         &ed_new_group, NULL, NULL, NULL,                    // Icons
  315.         (MenuSpec*) &XFE_EditorFrame::new_submenu_spec,        // Submenu spec
  316.         NULL , NULL,                                         // Generate proc
  317.         XFE_TOOLBAR_DELAY_LONG                                // Popup delay
  318.     },
  319.     { 
  320.         xfeCmdOpenPage,
  321.         DYNA_CASCADEBUTTON,
  322.         &ed_open_group, NULL, NULL, NULL,                    // Icons
  323.         NULL,                                                // Submenu spec
  324.         XFE_EditRecentMenu::generate, (void *) True,        // Generate proc
  325.         XFE_TOOLBAR_DELAY_LONG                                // Popup delay
  326.     },
  327.     { 
  328.         xfeCmdSave,
  329.         CASCADEBUTTON,
  330.         &ed_save_group, NULL, NULL, NULL,                    // Icons
  331.         (MenuSpec*) &XFE_EditorFrame::save_submenu_spec,    // Submenu spec
  332.         NULL , NULL,                                         // Generate proc
  333.         XFE_TOOLBAR_DELAY_LONG                                // Popup delay
  334.     },
  335.     { xfeCmdBrowsePage,    PUSHBUTTON,           &ed_browse_group  },
  336.     { 
  337.         xfeCmdPublish,
  338.         CASCADEBUTTON,
  339.         &ed_publish_group, NULL, NULL, NULL,                // Icons
  340.         (MenuSpec*) &XFE_EditorFrame::publish_submenu_spec,    // Submenu spec
  341.         NULL , NULL,                                         // Generate proc
  342.         XFE_TOOLBAR_DELAY_LONG                                // Popup delay
  343.     },
  344.     TOOLBAR_SEPARATOR,
  345.     { xfeCmdPrint,      PUSHBUTTON,           &ed_print_group   }, 
  346.     { xfeCmdSpellCheck,    PUSHBUTTON,           &ed_spellcheck_group },
  347.     TOOLBAR_SEPARATOR,
  348.     { xfeCmdInsertLink, PUSHBUTTON,           &ed_link_group    },
  349.     { xfeCmdInsertTarget, PUSHBUTTON,         &ed_target_group  },
  350.     { xfeCmdInsertImage, PUSHBUTTON,          &ed_image_group    },
  351.     { xfeCmdInsertHorizontalLine, PUSHBUTTON, &ed_hrule_group   },
  352.     { xfeCmdInsertTable, PUSHBUTTON,          &ed_table_group   },
  353.  
  354.     { NULL }
  355. };
  356.  
  357. static ToolbarSpec alignment_menu_spec[] = {
  358.     { xfeCmdSetAlignmentStyleLeft,     PUSHBUTTON, &ed_left_group },
  359.     { xfeCmdSetAlignmentStyleCenter, PUSHBUTTON, &ed_center_group },
  360.     { xfeCmdSetAlignmentStyleRight,     PUSHBUTTON, &ed_right_group },
  361.     { NULL }
  362. };
  363.  
  364. static ToolbarSpec editor_style_toolbar_spec[] = {
  365.  
  366.     { xfeCmdSetParagraphStyle, COMBOBOX },
  367.     { xfeCmdSetFontFace,       COMBOBOX },
  368.     { xfeCmdSetFontSize,       COMBOBOX },
  369.     { xfeCmdSetFontColor,      COMBOBOX },
  370.     TOOLBAR_SEPARATOR,
  371.  
  372.     { xfeCmdToggleCharacterStyleBold,       TOGGLEBUTTON, &ed_bold_group },
  373.     { xfeCmdToggleCharacterStyleItalic,       TOGGLEBUTTON, &ed_italic_group },
  374.     { xfeCmdClearAllStyles,                PUSHBUTTON  , &ed_clear_group },
  375.     TOOLBAR_SEPARATOR,
  376.  
  377.     { xfeCmdInsertBulletedList,    TOGGLEBUTTON, &ed_bullet_group },
  378.     { xfeCmdInsertNumberedList,    TOGGLEBUTTON, &ed_number_group },
  379.     TOOLBAR_SEPARATOR,
  380.  
  381.     { xfeCmdOutdent,    PUSHBUTTON, &ed_outdent_group },
  382.     { xfeCmdIndent,    PUSHBUTTON, &ed_indent_group },
  383.     { xfeCmdSetAlignmentStyle, CASCADEBUTTON, &ed_left_group, 0, 0, 0,
  384.       (MenuSpec*)&alignment_menu_spec },
  385.     { NULL }
  386. };
  387.  
  388. static MenuSpec fe_editor_document_popups[] =
  389. {
  390.     MENU_PUSHBUTTON(xfeCmdSetPageProperties),
  391.     MENU_SEPARATOR,
  392.     MENU_END
  393. };
  394.  
  395. static MenuSpec fe_editor_character_popups[] =
  396. {
  397.     MENU_PUSHBUTTON_1ARG("textProperties", xfeCmdDialog, "text"),
  398.     MENU_PUSHBUTTON_1ARG("paragraphProperties", xfeCmdDialog,
  399.                          "paragraph"),
  400.     MENU_SEPARATOR,
  401.     MENU_END
  402. };
  403.  
  404. static MenuSpec fe_editor_image_popups[] =
  405. {
  406.     MENU_PUSHBUTTON_1ARG("imageProperties", xfeCmdDialog, "image"),
  407.     MENU_PUSHBUTTON_1ARG("paragraphProperties", xfeCmdDialog,
  408.                          "paragraph"),
  409.     MENU_SEPARATOR,
  410.     MENU_END
  411. };
  412.  
  413. static MenuSpec fe_editor_tag_popups[] =
  414. {
  415.     MENU_PUSHBUTTON_1ARG("tagProperties", xfeCmdDialog, "tag"),
  416.     MENU_PUSHBUTTON_1ARG("paragraphProperties", xfeCmdDialog,
  417.                          "paragraph"),
  418.     MENU_SEPARATOR,
  419.     MENU_END
  420. };
  421.  
  422. static MenuSpec fe_editor_target_popups[] =
  423. {
  424.     MENU_PUSHBUTTON_1ARG("targetProperties", xfeCmdDialog, "target"),
  425.     MENU_PUSHBUTTON_1ARG("paragraphProperties", xfeCmdDialog,
  426.                          "paragraph"),
  427.     MENU_SEPARATOR,
  428.     MENU_END
  429. };
  430.  
  431. static MenuSpec fe_editor_hrule_popups[] =
  432. {
  433.     MENU_PUSHBUTTON_1ARG("hruleProperties", xfeCmdDialog, "hrule"),
  434.     MENU_PUSHBUTTON_1ARG("paragraphProperties", xfeCmdDialog,
  435.                          "paragraph"),
  436.     MENU_SEPARATOR,
  437.     MENU_END
  438. };
  439.  
  440. static MenuSpec fe_editor_table_insert_popups[] =
  441. {
  442.     MENU_PUSHBUTTON(xfeCmdInsertTable),
  443.     MENU_PUSHBUTTON(xfeCmdInsertTableRow),
  444.     MENU_PUSHBUTTON(xfeCmdInsertTableColumn),
  445.     MENU_PUSHBUTTON(xfeCmdInsertTableCell),
  446.     MENU_END
  447. };
  448.  
  449. static MenuSpec fe_editor_table_delete_popups[] =
  450. {
  451.     MENU_PUSHBUTTON(xfeCmdDeleteTable),
  452.     MENU_PUSHBUTTON(xfeCmdDeleteTableRow),
  453.     MENU_PUSHBUTTON(xfeCmdDeleteTableColumn),
  454.     MENU_PUSHBUTTON(xfeCmdDeleteTableCell),
  455.     MENU_END
  456. };
  457.  
  458. static MenuSpec fe_editor_table_popups[] =
  459. {
  460.     MENU_PUSHBUTTON_1ARG("tableProperties", xfeCmdDialog, "table"),
  461.     MENU_MENU("insert" ,fe_editor_table_insert_popups),
  462.     MENU_MENU("delete" ,fe_editor_table_delete_popups),
  463.     MENU_SEPARATOR,
  464.     MENU_END
  465. };
  466.  
  467. static MenuSpec fe_editor_link_popups[] =
  468. {
  469.     MENU_PUSHBUTTON_1ARG("linkProperties", xfeCmdDialog, "link"),
  470.     MENU_PUSHBUTTON(xfeCmdOpenLinkNew),
  471.     MENU_PUSHBUTTON(xfeCmdOpenLinkEdit),
  472.     MENU_PUSHBUTTON(xfeCmdAddLinkBookmark),
  473.     MENU_PUSHBUTTON(xfeCmdCopyLink),
  474.     MENU_PUSHBUTTON(xfeCmdRemoveLink),
  475.     MENU_SEPARATOR,
  476.     MENU_END
  477. };
  478.  
  479. static MenuSpec fe_editor_insert_link_popups[] =
  480. {
  481.     MENU_PUSHBUTTON(xfeCmdInsertLink),
  482.     MENU_SEPARATOR,
  483.     MENU_END
  484. };
  485.  
  486. static MenuSpec fe_editor_edit_popups[] =
  487. {
  488.     MENU_PUSHBUTTON(xfeCmdCut),
  489.     MENU_PUSHBUTTON(xfeCmdCopy),
  490.     MENU_PUSHBUTTON(xfeCmdPaste),
  491.     MENU_END
  492. };
  493.  
  494. #if 0
  495. static MenuSpec fe_editor_title_popups[] =
  496. {
  497.     { "title", LABEL },
  498.     MENU_SEPARATOR,
  499.     MENU_END
  500. };
  501. #endif
  502.  
  503. static MenuSpec fe_editor_show_options_popups[] =
  504. {
  505.     MENU_SEPARATOR,
  506.     MENU_PUSHBUTTON(xfeCmdToggleMenubar),
  507.     MENU_PUSHBUTTON(xfeCmdToggleNavigationToolbar),
  508.     MENU_PUSHBUTTON(xfeCmdToggleFormatToolbar),
  509.     MENU_END
  510. };
  511.  
  512. XFE_PopupMenu*
  513. fe_EditorNewPopupMenu(XFE_Frame* frame, Widget parent)
  514. {
  515.     MWContext*     context = frame->getContext();
  516.     XFE_PopupMenu* popup;
  517.     ED_ElementType e_type;
  518.     MenuSpec*      list;
  519.  
  520.     if (!EDT_IS_EDITOR(context))
  521.         return NULL;
  522.  
  523.     popup = new XFE_PopupMenu("popup",frame, parent, NULL);
  524.  
  525.     e_type = EDT_GetCurrentElementType(context);
  526.  
  527.     switch (e_type) {
  528.     case ED_ELEMENT_IMAGE:       list = fe_editor_image_popups;  break;
  529.     case ED_ELEMENT_UNKNOWN_TAG: list = fe_editor_tag_popups;    break;
  530.     case ED_ELEMENT_TARGET:      list = fe_editor_target_popups; break;
  531.     case ED_ELEMENT_HRULE:       list = fe_editor_hrule_popups;  break;
  532.     case ED_ELEMENT_TEXT:
  533.     default:                     list = fe_editor_character_popups; break;
  534.     }
  535.  
  536.     popup->addMenuSpec(list);
  537.  
  538.     /*
  539.      *    Document Props..
  540.      */
  541.     popup->addMenuSpec(fe_editor_document_popups);
  542.  
  543.     /*
  544.      *    Table support.
  545.      */
  546.     if (EDT_IsInsertPointInTable(context) != 0) {
  547.         popup->addMenuSpec(fe_editor_table_popups);
  548.     }
  549.     
  550.     /*
  551.      *    Link stuff.
  552.      */
  553.     if (EDT_GetHREF(context)) { 
  554.         popup->addMenuSpec(fe_editor_link_popups);
  555.     } else {
  556.         popup->addMenuSpec(fe_editor_insert_link_popups);
  557.     }
  558.     
  559.     /*
  560.      *    Add cut&paste menu.
  561.      */
  562.     popup->addMenuSpec(fe_editor_edit_popups);
  563.     
  564.     /*
  565.      *    If they accidently deleted the menubar, help them out.
  566.      */
  567.     if (!CONTEXT_DATA(context)->show_menubar_p)
  568.         popup->addMenuSpec(fe_editor_show_options_popups);
  569.  
  570.     return popup;
  571. }
  572.  
  573. static MenuSpec*
  574. fe_editor_create_plugin_menu(MenuSpec* static_spec)
  575. {
  576.     //
  577.     //    Count the number of static entries in the tools menu.
  578.     //
  579.     int32 nstatics = 0;
  580.     if (static_spec != NULL) {
  581.         while (static_spec[nstatics].menuItemName != NULL) {
  582.             nstatics++;
  583.         }
  584.     }
  585.     
  586.     //
  587.     //    Register Java Plugin Commands.
  588.     //
  589.     int32 ncategories = EDT_NumberOfPluginCategories();
  590.     
  591.     if (!ncategories)
  592.         return static_spec; // the static menu will do fine
  593.     
  594.     MenuSpec* menu_spec = new MenuSpec[ncategories+nstatics+1];
  595.     memset(menu_spec, 0, sizeof(MenuSpec) * (ncategories+nstatics+1));
  596.  
  597.     for (int n = 0; n < nstatics; n++)
  598.         menu_spec[n] = static_spec[n];
  599.     
  600.     int32 category_index = 0;
  601.     for (int32 category = 0; category < ncategories; category++) {
  602.     
  603.         char* category_name = XP_STRDUP(EDT_GetPluginCategoryName(category));
  604.  
  605.         if (!category_name)
  606.             continue;
  607.  
  608.         int32 nplugins = EDT_NumberOfPlugins(category);
  609.  
  610.         if (!nplugins) // no plugins for this category.
  611.             continue;
  612.  
  613.         MenuSpec* category_spec = new MenuSpec[nplugins+1];
  614.         memset(category_spec, 0, sizeof(MenuSpec) * (nplugins+1));
  615.  
  616.         int32 plugin = 0;
  617.         for (; plugin < nplugins; plugin++) {
  618.             char buf[64];
  619.             sprintf(buf, "javaPlugin_%d_%d", category, plugin);
  620.             char* command_name = Command::intern(buf);
  621.  
  622.             category_spec[plugin].menuItemName = command_name;
  623.             category_spec[plugin].tag = PUSHBUTTON;
  624.         }
  625.         category_spec[plugin].menuItemName = NULL; // delimit paranoia
  626.  
  627.         menu_spec[nstatics+category_index].menuItemName = category_name;
  628.         menu_spec[nstatics+category_index].tag = CASCADEBUTTON;
  629.         menu_spec[nstatics+category_index].submenu = category_spec;
  630.         category_index++;
  631.     }
  632.     menu_spec[nstatics+category_index].menuItemName = NULL; // delimit paranoia
  633.  
  634.     return menu_spec;
  635. }
  636.  
  637. static MenuSpec*
  638. fe_editor_create_font_face_menu(XFE_Frame* frame)
  639. {
  640.     CommandType  command_id = xfeCmdSetFontFace;
  641.     XFE_Command* handler = frame->getCommand(command_id);
  642.  
  643.     if (!handler)
  644.         return NULL;
  645.  
  646.     XFE_CommandParameters* params = handler->getParameters(frame);
  647.     unsigned n;
  648.  
  649.     for (n = 0; params[n].name != NULL; n++)
  650.         ;
  651.  
  652.     MenuSpec* spec = (MenuSpec*)XP_CALLOC((n+1), sizeof(MenuSpec));
  653.     
  654.     for (n = 0; params[n].name != NULL; n++) {
  655.         spec[n].menuItemName = command_id;
  656.         spec[n].tag = TOGGLEBUTTON;
  657.         spec[n].radioGroupName = editor_radio_group_name;
  658.         spec[n].cmd_name = command_id;
  659.         spec[n].cmd_args[0] = params[n].name;
  660.         spec[n].callData = params[n].data;
  661.     }
  662.  
  663.     return spec;
  664. }
  665.  
  666. static MenuSpec* i_tools_menu = 0;
  667. static MenuSpec* i_font_menu = 0;
  668.  
  669. MenuSpec*
  670. fe_EditorInstanciateMenu(XFE_Frame* f, MenuSpec* spec)
  671. {
  672.     //
  673.     //    Find the Tools menu and install Composer Plugin menu.
  674.     //
  675.     for (unsigned n = 0; spec[n].menuItemName != NULL; n++) {
  676.  
  677.         if (XP_STRCMP(spec[n].menuItemName, xfeMenuTools) == 0) {
  678.             
  679.             if (!i_tools_menu)
  680.                 i_tools_menu = fe_editor_create_plugin_menu(spec[n].submenu);
  681.             
  682.             spec[n].submenu = i_tools_menu;
  683.         }
  684.  
  685.         else if (XP_STRCMP(spec[n].menuItemName, xfeMenuFormat) == 0) {
  686.             MenuSpec* fspec = spec[n].submenu;
  687.             for (unsigned m = 0; fspec[m].menuItemName != NULL; m++) {
  688.                 if (XP_STRCMP(fspec[m].menuItemName, "fontStyleMenu") == 0) {
  689.  
  690.                     if (!i_font_menu)
  691.                         i_font_menu = fe_editor_create_font_face_menu(f);
  692.  
  693.                     fspec[m].submenu = i_font_menu; 
  694.                 }
  695.             }
  696.         }
  697.     }
  698.     
  699.     return spec;
  700. }
  701.  
  702. static MenuSpec* initialized_menu_bar_spec = 0;
  703.  
  704. XFE_EditorFrame::XFE_EditorFrame(Widget toplevel,
  705.                                  XFE_Frame *parent_frame,
  706.                                  Chrome *chromespec)
  707.   : XFE_Frame("Editor", toplevel, parent_frame, FRAME_EDITOR, chromespec, True, True, True)
  708. {
  709.   geometryPrefName = "editor";
  710.  
  711.   if (parent_frame)
  712.     fe_copy_context_settings(m_context, parent_frame->getContext());
  713.  
  714.   // create html view
  715.   XFE_EditorView *editorview = new XFE_EditorView(this, 
  716.                                                   getViewParent(),
  717.                                                   NULL,
  718.                                                   m_context);
  719.  
  720.   editorview->registerInterest(XFE_EditorView::newURLLoading, 
  721.         this,
  722.         (XFE_FunctionNotification)newPageLoading_cb);
  723.  
  724.   XtVaSetValues(editorview->getBaseWidget(),
  725.         XmNleftAttachment, XmATTACH_FORM,
  726.         XmNtopAttachment, XmATTACH_FORM,
  727.         XmNrightAttachment, XmATTACH_FORM,
  728.         XmNbottomAttachment, XmATTACH_FORM,
  729.         NULL);
  730.  
  731.   /*
  732.    *    Hacks to make old XFE code work. These should go away
  733.    *    as old XFE code is sent to pasture.
  734.    */
  735.   CONTEXT_DATA (m_context)->show_character_toolbar_p = TRUE;
  736.   CONTEXT_DATA (m_context)->show_paragraph_toolbar_p = TRUE;
  737.   CONTEXT_DATA (m_context)->top_area = getChromeParent();
  738.   CONTEXT_DATA (m_context)->menubar = m_menubar->getBaseWidget();
  739.  
  740.   setView(editorview);
  741.  
  742.   if (!initialized_menu_bar_spec)
  743.       initialized_menu_bar_spec = fe_EditorInstanciateMenu(this,
  744.                                                            menu_bar_spec);
  745.  
  746.   setMenubar(initialized_menu_bar_spec);
  747.   setToolbar((ToolbarSpec*)&editor_file_toolbar_spec);
  748.  
  749.   m_format_toolbar = new XFE_EditorToolbar(this,
  750.                                            m_toolbox,
  751.                                            "editorFormattingToolbar",
  752.                                     (ToolbarSpec*)&editor_style_toolbar_spec,
  753.                                            True);
  754.  
  755.   fe_set_scrolled_default_size(m_context);
  756.  
  757.   m_toolbar->show();
  758. //  m_format_toolbar->show();
  759.   editorview->show();
  760.  
  761.   m_dashboard->setShowStatusBar(True);
  762.   m_dashboard->setShowProgressBar(True);
  763.  
  764.   // Configure the toolbox for the first time
  765.   configureToolbox();
  766. }
  767.  
  768. int
  769. XFE_EditorFrame::getURL(URL_Struct *url, Boolean skip_get_url)
  770. {
  771.   XFE_EditorView *eview = (XFE_EditorView*)m_view;
  772.  
  773.   return eview->getURL(url, skip_get_url);
  774. }
  775.  
  776. XFE_CALLBACK_DEFN(XFE_EditorFrame, navigateToURL)(XFE_NotificationCenter*, void*, void* /*callData*/)
  777. {
  778.   // int status;
  779.   // URL_Struct *url_struct = (URL_Struct*)callData;
  780.   //
  781.   // status = getURL(url_struct, FALSE);
  782.   //
  783.   // if (status >= 0)
  784.   //  {
  785.   //     if (url_struct && url_struct->address)
  786.   //       m_urlBar->recordURL(url_struct);
  787.   //  }
  788. }
  789.  
  790. XFE_CALLBACK_DEFN(XFE_EditorFrame, newPageLoading)(XFE_NotificationCenter*, void*, void* /*callData*/)
  791. {
  792.   // URL_Struct *url = (URL_Struct*)callData;
  793.   //
  794.   // m_urlBar->setURLString(url);
  795. }
  796.  
  797. MWContext*
  798. XFE_EditorFrame::getContext()
  799. {
  800.   if (m_view)
  801.     return m_view->getContext();
  802.   else
  803.     return NULL;
  804. }
  805.  
  806. #ifdef DEBUG_djw_NOT_RIGHT_NOW_THANK_YOU
  807. #define TRACE(x) printf x
  808. #else
  809. #define TRACE(x)
  810. #endif
  811.  
  812. Boolean
  813. XFE_EditorFrame::isCommandEnabled(CommandType cmd,
  814.                                   void* calldata, XFE_CommandInfo* info)
  815. {
  816.     TRACE(("XFE_EditorFrame::isCommandEnabled(%d,0x%x)\n", cmd, calldata));
  817.     
  818.     if (cmd == xfeCmdToggleFormatToolbar) {
  819.         return True;
  820.     }
  821.     
  822.     return XFE_Frame::isCommandEnabled(cmd, calldata, info);
  823. }
  824.  
  825.  
  826. Boolean
  827. XFE_EditorFrame::isCommandSelected(CommandType cmd, 
  828.                                   void* calldata, XFE_CommandInfo* info)
  829. {
  830.     TRACE(("XFE_EditorFrame::isCommandSelected(%s,0x%x)\n",
  831.            Command::getString(cmd), calldata));
  832.  
  833.     return XFE_Frame::isCommandSelected(cmd, calldata, info);
  834. }
  835.  
  836. void
  837. XFE_EditorFrame::doCommand(CommandType cmd,
  838.                            void* calldata, XFE_CommandInfo* info)
  839. {
  840.     TRACE(("XFE_EditorFrame::doCommand(%d,0x%x)\n", cmd, calldata));
  841.  
  842.     if (cmd == xfeCmdToggleFormatToolbar) {
  843.             // Toggle the showing state
  844.             m_format_toolbar->toggle();
  845.  
  846.             //
  847.             // The doAttachments() call is needed in case the resulting
  848.             // toggle operation causes all toolbars to go away.  The frame
  849.             // needs to attach things accordingly.
  850.             //
  851.             
  852.             // Do the attachments
  853.             doAttachments();
  854.  
  855.             //
  856.             // The toolboxItemChangeShowing() call is needed to make the 
  857.             // state of toolbars persistent.
  858.             //
  859.             
  860.             // Update prefs
  861.             toolboxItemChangeShowing(m_format_toolbar);
  862.  
  863.             //
  864.             // Im not sure if the following invocation is needed, but 
  865.             // every single other frame that that toggles toolbar has it.
  866.             //
  867.  
  868.             // Update chrome
  869.             notifyInterested(XFE_View::chromeNeedsUpdating);
  870.     } else if (cmd == xfeCmdEditPreferences) { // override BrowserFrame
  871.         fe_showEditorPreferences(this, getContext());
  872.     } else {
  873.         XFE_Frame::doCommand(cmd, calldata, info);
  874.     }
  875. }
  876.  
  877. Boolean
  878. XFE_EditorFrame::handlesCommand(CommandType cmd,
  879.                                 void* calldata, XFE_CommandInfo* info)
  880. {
  881.     TRACE(("XFE_EditorFrame::handlesCommand(%d,0x%x)\n", cmd, calldata));
  882.  
  883.     if (cmd == xfeCmdToggleFormatToolbar) {
  884.         return True;
  885.     }
  886.  
  887.     return XFE_Frame::handlesCommand(cmd, calldata, info);
  888. }
  889.  
  890. char*
  891. XFE_EditorFrame::commandToString(CommandType cmd,
  892.                                  void* calldata, XFE_CommandInfo* info)
  893. {
  894.     TRACE(("XFE_EditorFrame::commandToString(%d,0x%x)\n", cmd, calldata));
  895.     if (cmd == xfeCmdToggleFormatToolbar) {
  896.  
  897.         Widget widget = NULL;
  898.         Boolean show = !m_format_toolbar->isShown();
  899.         
  900.         if (info != NULL)
  901.             widget = info->widget;
  902.         
  903.         return getShowHideLabelString(cmd, show, widget);
  904.  
  905.     } else {
  906.         return XFE_Frame::commandToString(cmd, calldata, info);
  907.     }
  908. }
  909.  
  910. XFE_Command*
  911. XFE_EditorFrame::getCommand(CommandType cmd)
  912. {
  913.     XFE_Command* handler = getView()->getCommand(cmd);
  914.  
  915.     if (handler != NULL)
  916.         return handler;
  917.  
  918.     return XFE_Frame::getCommand(cmd);
  919. }
  920.  
  921. extern "C" Boolean
  922. fe_save_file_check(MWContext* context,
  923.                    Boolean file_must_exist, Boolean auto_save);
  924.  
  925. XP_Bool
  926. XFE_EditorFrame::isOkToClose()
  927. {
  928.     MWContext* context = getContext();
  929.  
  930.     if (fe_save_file_check(context, False, False)) {
  931.  
  932.         /*
  933.          *    We've already had this discussion....
  934.          */
  935.         EDT_SetDirtyFlag(context, FALSE);
  936.         
  937.         return TRUE;
  938.     } else {
  939.         return FALSE;
  940.     }
  941. }
  942.  
  943. static void
  944. editor_do_close_cb(void* closure)
  945. {
  946.     XFE_EditorFrame* frame = (XFE_EditorFrame *)closure;
  947.  
  948.     frame->XFE_Frame::doClose();
  949. }
  950.  
  951. void
  952. XFE_EditorFrame::doClose()
  953. {
  954.     MWContext*     context = getContext();
  955.     History_entry* hist_entry = SHIST_GetCurrent(&context->hist);
  956.     char*          url = NULL;
  957.     
  958.     if (hist_entry != NULL)
  959.         url = hist_entry->address;
  960.     
  961.     EDT_PreClose(context, url, editor_do_close_cb, (void*)this);
  962. }
  963.  
  964. //
  965. // These 2 are here cause the editor does not have all the fancy toolbox 
  966. // and logo crap that the other frames do, so the configureLogo() method
  967. // cuases the frame to do nothing and getLogo() always returns null so that
  968. // the logo never appears
  969. //
  970. void
  971. XFE_EditorFrame::configureLogo()
  972. {
  973. }
  974. //////////////////////////////////////////////////////////////////////////
  975. XFE_Logo *
  976. XFE_EditorFrame::getLogo()
  977. {
  978.     return NULL;
  979. }
  980. //////////////////////////////////////////////////////////////////////////
  981.  
  982.  
  983. //
  984. //    Moved here from editor.c. I think (?) the only place this is called
  985. //    now is for a cancelled remote save. See cmd/xfe/editor.c, rev 1.146
  986. //    for audit trail.
  987. //
  988. extern "C" void
  989. fe_EditorDelete(MWContext* context)
  990. {
  991.  
  992.     XFE_Frame* frame = ViewGlue_getFrame(context);
  993.  
  994.     frame->delete_response();
  995. }
  996.  
  997. //
  998. //    This guy is called when we just want to get the hell out of here.
  999. //    No discussions with the user, just go. This is used when we load a
  1000. //    bad url or something like that. We don't know it's bogus until after
  1001. //    we have made the window, loaded the url, and generaly got into a state
  1002. //    we dont' want to be in. So just go, skip the PreClose() stuff and go.
  1003. //
  1004. extern "C" void
  1005. fe_EditorKill(MWContext* context)
  1006. {
  1007.     XFE_Frame* frame = ViewGlue_getFrame(context);
  1008.  
  1009.     /*
  1010.      *    Mark it is a new document, that is not dirty, so that we don't
  1011.      *    bother with "do you really want to quit?" dialogs.
  1012.      */
  1013.     context->is_new_document = TRUE;
  1014.     EDT_SetDirtyFlag(context, FALSE);
  1015.  
  1016.     frame->XFE_Frame::doClose(); // skip PreClose, call super.
  1017. }
  1018.  
  1019. // --------------------------------------------------------------------------
  1020. struct fe_editor_pre_open_info
  1021. {
  1022.     Widget      toplevel;
  1023.     XFE_Frame*  parent_frame;
  1024.     Chrome*     chromespec;
  1025.     char*       address;
  1026. };
  1027.  
  1028. static void 
  1029. fe_editor_pre_open_cb(XP_Bool cancelled, char* address, void* closure)
  1030. {
  1031.     fe_editor_pre_open_info* info = (fe_editor_pre_open_info*)closure;
  1032.  
  1033.     if (!cancelled) {
  1034.  
  1035.         MWContext*       context = NULL;
  1036.         XFE_EditorFrame* theFrame;
  1037.  
  1038.         theFrame = new XFE_EditorFrame(info->toplevel,
  1039.                                        info->parent_frame,
  1040.                                        info->chromespec);
  1041.  
  1042.         theFrame->show();
  1043.  
  1044.         context = theFrame->getContext();
  1045.  
  1046.         fe_UserActivity(context);
  1047.         xfe2_EditorInit(context); // im registration, focus event handlers, ...
  1048.     
  1049.         if (address == NULL) {
  1050.             //
  1051.             // NOTE:  create a blank address...
  1052.             //
  1053.             address = "about:editfilenew";
  1054.         }
  1055.  
  1056.         URL_Struct* url = NET_CreateURLStruct(address, NET_NORMAL_RELOAD);
  1057.         theFrame->getURL(url, FALSE);
  1058.     }
  1059.  
  1060.     if (info->address)
  1061.         XP_FREE(info->address);
  1062.  
  1063.     delete info;
  1064. }
  1065.  
  1066. MWContext*
  1067. fe_showEditor(Widget      toplevel,
  1068.               XFE_Frame*  parent_frame,
  1069.               Chrome*     chromespec,
  1070.               URL_Struct* url)
  1071. {
  1072.     // not a static global, since we can have multiple editors.
  1073.     MWContext*       context = NULL;
  1074.  
  1075.     if (parent_frame != NULL)
  1076.         context = parent_frame->getContext();
  1077.  
  1078.     if (fe_IsEditorDisabled()) {
  1079.         if (context != NULL)
  1080.             FE_Alert(context, XP_GetString(XFE_DISABLED_BY_ADMIN));
  1081.         return NULL;
  1082.     }
  1083.  
  1084.     /*
  1085.      *    Should test for others we know are bogus. There is a BE call
  1086.      *    for this.
  1087.      */
  1088.     if (url != NULL && XP_STRNCMP(url->address, "about:", 6) == 0) {
  1089.         if (context != NULL)
  1090.             FE_Alert(context, XP_GetString(XFE_EDITOR_ALERT_ABOUT_DOCUMENT));
  1091.         return NULL;
  1092.     }
  1093.  
  1094.     fe_editor_pre_open_info* info = new fe_editor_pre_open_info;
  1095.  
  1096.     info->toplevel = toplevel;
  1097.     info->parent_frame = parent_frame;
  1098.     info->chromespec = chromespec;
  1099.     if (url != NULL && url->address != NULL)
  1100.         info->address = XP_STRDUP(url->address);
  1101.     else
  1102.         info->address = NULL;
  1103.         
  1104.     if (context != NULL && url != NULL && url->address != NULL) {
  1105.         EDT_PreOpen(context, info->address, fe_editor_pre_open_cb, info);
  1106.     } else {
  1107.         fe_editor_pre_open_cb(FALSE, info->address, info);
  1108.     }
  1109.     
  1110.     return NULL;
  1111. }
  1112.  
  1113. // --------------------------------------------------------------------------
  1114.  
  1115. MWContext*
  1116. fe_EditorNew(MWContext* context,
  1117.              XFE_Frame* parent_frame,
  1118.              Chrome*    chromespec,
  1119.              char*      address)
  1120. {
  1121.     Widget      toplevel;
  1122.     MWContext*  new_context;
  1123.     URL_Struct* url = NULL;
  1124.  
  1125.     if (address != NULL)
  1126.         url = NET_CreateURLStruct(address, NET_NORMAL_RELOAD);
  1127.     
  1128.     toplevel = XtParent(CONTEXT_WIDGET(context));
  1129.  
  1130.     //
  1131.     //    If there is no parent_frame, try to derive one from the context.
  1132.     //    Otherwise the constructor doesn't copy the context bits!
  1133.     //
  1134.     if (parent_frame == NULL && context != NULL)
  1135.         parent_frame = ViewGlue_getFrame(context);
  1136.     
  1137.     new_context = fe_showEditor(toplevel, parent_frame, chromespec, url);
  1138.  
  1139.     return new_context;
  1140. }
  1141.  
  1142. static MWContext*
  1143. fe_editor_find_context(char* address, int type)
  1144. {
  1145.     struct fe_MWContext_cons* rest;
  1146.     MWContext* context;
  1147.     History_entry* hist_entry;
  1148.  
  1149.     if (!address)
  1150.         return NULL;
  1151.  
  1152.     for (rest = fe_all_MWContexts; rest; rest = rest->next) {
  1153.         context = rest->context;
  1154.         if (context->type == type) {
  1155.  
  1156.             char* hist_address = NULL;
  1157.             hist_entry = SHIST_GetCurrent(&context->hist);
  1158.             if (hist_entry != NULL)
  1159.                 hist_address = hist_entry->address;
  1160.  
  1161.             //
  1162.             //    If the addresses match, just remap the existing one.
  1163.             //    Note the following hack, because it happens so much:
  1164.             //    "www.foo.com/file.html" == "http://www.foo.com/file.html"
  1165.             //    "/dir/file.html" == "file:/dir/file.html"
  1166.             //    "/dir/file.html" == "file:///dir/file.html"
  1167.             //
  1168.             if (hist_address != NULL && 
  1169.                 (XP_STRCMP(hist_address, address) == 0 /* exact */
  1170.  
  1171.                  )
  1172.                 )
  1173.                 return context;
  1174.         }
  1175.     }
  1176.     return NULL;
  1177. }
  1178.  
  1179. static void
  1180. fe_map_raise_timeout(XtPointer closure, XtIntervalId*)
  1181. {
  1182.     MWContext* context = (MWContext *)closure;
  1183.     Widget     widget = CONTEXT_WIDGET(context);
  1184.     Display*   display = XtDisplay(widget);
  1185.     Window     window = XtWindow(widget);
  1186.  
  1187.  
  1188.     XMapWindow(display, window);
  1189.     XRaiseWindow(display, window);
  1190.  
  1191. }
  1192.  
  1193. void
  1194. fe_map_raise_window_when_idle(MWContext* context)
  1195. {
  1196.     /*
  1197.      *    Delay the raise until after any dialogs, etc have
  1198.      *    been unmanaged. Otherwise we bounce backwards and forwards,
  1199.      *    and sometimes the window is left unraised.
  1200.      */
  1201.     XtAppAddTimeOut(fe_XtAppContext, 0, fe_map_raise_timeout,
  1202.                     (XtPointer)context);
  1203. }
  1204.  
  1205. MWContext* 
  1206. fe_EditorEdit(MWContext* context,
  1207.              XFE_Frame*  parent_frame,
  1208.              Chrome*     chromespec,
  1209.              char*       address)
  1210. {
  1211.     History_entry* hist_ent;
  1212.  
  1213.     if (address == NULL) { /* edit this page */
  1214.         hist_ent = SHIST_GetCurrent(&context->hist);
  1215.         if (hist_ent != NULL)
  1216.             address = hist_ent->address;
  1217.     }
  1218.  
  1219.     MWContext* new_context = fe_editor_find_context(address, MWContextEditor);
  1220.  
  1221.     if (new_context) {
  1222.         fe_map_raise_window_when_idle(new_context);
  1223.     } else {
  1224.         new_context = fe_EditorNew(context, parent_frame, chromespec, address);
  1225.     }
  1226.  
  1227.     return new_context;
  1228. }
  1229.  
  1230. MWContext* 
  1231. fe_EditorOpen(MWContext* context,
  1232.              XFE_Frame*  parent_frame,
  1233.              Chrome*     chromespec)
  1234. {
  1235.     MWContext* new_context = XP_FindContextOfType(context, MWContextEditor);
  1236.  
  1237.     if (new_context) {
  1238.         fe_map_raise_window_when_idle(new_context);
  1239.     } else {
  1240.         new_context = fe_EditorNew(context, parent_frame, chromespec, NULL);
  1241.     }
  1242.  
  1243.     return new_context;
  1244. }
  1245.  
  1246. extern "C" void
  1247. fe_HackEditorNotifyToolbarUpdated(MWContext* context)
  1248. {
  1249.     XFE_Frame* frame = ViewGlue_getFrame(context);
  1250.  
  1251.     if (frame)
  1252.         frame->notifyInterested(XFE_View::chromeNeedsUpdating, 0);
  1253. }
  1254.  
  1255. //
  1256. //    This function exists because fe_showEditorPreferences(), though
  1257. //    defined as a C function, has C++ class as the first arg, and the
  1258. //    first arg can be derived from the second! Joy.
  1259. //
  1260. void
  1261. fe_EditorShowNewPreferences(MWContext* context)
  1262. {
  1263.     XFE_Frame* frame = ViewGlue_getFrame(context);
  1264.  
  1265.     if (frame)
  1266.         fe_showEditorPreferences(frame, context);
  1267. }
  1268.  
  1269. //////////////////////////////////////////////////////////////////////////
  1270. //
  1271. // Toolbox methods
  1272. //
  1273. //////////////////////////////////////////////////////////////////////////
  1274. void
  1275. XFE_EditorFrame::toolboxItemSnap(XFE_ToolboxItem * item)
  1276. {
  1277.     XP_ASSERT( item == m_toolbar || item == m_format_toolbar );
  1278.  
  1279.     // Composition
  1280.     fe_globalPrefs.composer_composition_toolbar_position = m_toolbar->getPosition();
  1281.  
  1282.     // Formatting
  1283. fe_globalPrefs.composer_formatting_toolbar_position = m_format_toolbar->getPosition();
  1284. }
  1285. //////////////////////////////////////////////////////////////////////////
  1286. void
  1287. XFE_EditorFrame::toolboxItemClose(XFE_ToolboxItem * item)
  1288. {
  1289.     XP_ASSERT( item != NULL );
  1290.  
  1291.     // Composition
  1292.     if (item == m_toolbar)
  1293.     {
  1294.         fe_globalPrefs.composer_composition_toolbar_open = False;
  1295.     }
  1296.     // Formatting
  1297.     else if (item == m_format_toolbar)
  1298.     {
  1299.         fe_globalPrefs.composer_formatting_toolbar_open = False;
  1300.     }
  1301. }
  1302. //////////////////////////////////////////////////////////////////////////
  1303. void
  1304. XFE_EditorFrame::toolboxItemOpen(XFE_ToolboxItem * item)
  1305. {
  1306.     XP_ASSERT( item != NULL );
  1307.  
  1308.     // Composition
  1309.     if (item == m_toolbar)
  1310.     {
  1311.         fe_globalPrefs.composer_composition_toolbar_open = True;
  1312.     }
  1313.     // Formatting
  1314.     else if (item == m_format_toolbar)
  1315.     {
  1316.         fe_globalPrefs.composer_formatting_toolbar_open = True;
  1317.     }
  1318. }
  1319. //////////////////////////////////////////////////////////////////////////
  1320. void
  1321. XFE_EditorFrame::toolboxItemChangeShowing(XFE_ToolboxItem * item)
  1322. {
  1323.     XP_ASSERT( item != NULL );
  1324.  
  1325.     // Composition
  1326.     if (item == m_toolbar)
  1327.     {
  1328.         fe_globalPrefs.composer_composition_toolbar_showing = item->isShown();
  1329.     }
  1330.     // Formatting
  1331.     else if (item == m_format_toolbar)
  1332.     {
  1333.         fe_globalPrefs.composer_formatting_toolbar_showing = item->isShown();
  1334.     }
  1335. }
  1336. //////////////////////////////////////////////////////////////////////////
  1337. void
  1338. XFE_EditorFrame::configureToolbox()
  1339. {
  1340.     // If a the frame was constructed with a chromespec, then we ignore
  1341.     // all the preference magic.
  1342.     if (m_chromespec_provided)
  1343.     {
  1344.         return;
  1345.     }
  1346.  
  1347.     // Make sure the toolbox is alive
  1348.     if (!m_toolbox || (m_toolbox && !m_toolbox->isAlive()))
  1349.     {
  1350.         return;
  1351.     }
  1352.  
  1353.     // Composition
  1354.     if (m_toolbar)
  1355.     {
  1356.         m_toolbar->setShowing(fe_globalPrefs.composer_composition_toolbar_showing);
  1357.         m_toolbar->setOpen(fe_globalPrefs.composer_composition_toolbar_open);
  1358.         m_toolbar->setPosition(fe_globalPrefs.composer_composition_toolbar_position);
  1359.     }
  1360.  
  1361.     // Formatting
  1362.     if (m_format_toolbar)
  1363.     {
  1364.         m_format_toolbar->setShowing(fe_globalPrefs.composer_formatting_toolbar_showing);
  1365.         m_format_toolbar->setOpen(fe_globalPrefs.composer_formatting_toolbar_open);
  1366.         m_format_toolbar->setPosition(fe_globalPrefs.composer_formatting_toolbar_position);
  1367.     }
  1368. }
  1369. //////////////////////////////////////////////////////////////////////////
  1370.  
  1371.  
  1372. // EOF
  1373.