home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / winfe / edview.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  128.9 KB  |  3,540 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. // edview.cpp : implementation of the CNetscapeEditView class
  20. //
  21. // Primary Command handling for Editor window
  22. //
  23. // Created 9/11/95 by CLM
  24. //
  25.  
  26. #include "stdafx.h"
  27. #ifdef EDITOR
  28. #include "edview.h"
  29. #include "edprops.h"
  30. #include "edt.h"
  31. #include "mainfrm.h"
  32. #include "edframe.h"
  33. #include "edres2.h"
  34. #include "property.h"
  35. #include "edttypes.h"
  36. #include "edtable.h"
  37. #include "prefapi.h"
  38. #include "libi18n.h"
  39. #include "intl_csi.h"
  40. #include "compfrm.h"
  41. #include "edtclass.h"
  42. #include "abdefn.h"
  43.  
  44. #ifdef _IME_COMPOSITION
  45. #define CLEARBIT(A, N)    A&=~N
  46. #define SETBIT(A, N)    A|=N
  47.  
  48.     #ifdef XP_WIN16
  49.         #include "ime16.h"
  50.     #else
  51.         #include "intlwin.h"
  52.     #endif //XP_WIN16 else XP_WIN32
  53. #endif
  54. #ifdef _DEBUG
  55. #ifdef XP_WIN16
  56. #if 0
  57. char * g_buffers[1000];
  58. int g_numbuffers=0;
  59.  
  60. void
  61. addToBuffer(const char *p_str)
  62. {
  63.     g_buffers[g_numbuffers++]=XP_STRDUP(p_str);
  64. }
  65.  
  66. void addToBufferLONG(LONG p_int)
  67. {
  68.     char t_def[255];
  69.     ltoa(p_int,t_def,10);
  70.     g_buffers[g_numbuffers++]=(char *)XP_STRDUP(t_def);
  71.     
  72. }
  73.  
  74. void
  75. addToBuffer(LPARAM p_result)
  76. {
  77.     const char *t_char;
  78.     switch (p_result)
  79.     {
  80.     case IME_RS_DISKERROR: t_char="IME_RS_DISK_ERROR";break;
  81.     case IME_RS_ERROR: t_char="IME_RS_ERRPR";break;
  82.     case IME_RS_ILLEGAL: t_char="IME_RS_ILLEGAL";break;
  83.     case IME_RS_INVALID: t_char="IME_RS_INVALID";break;
  84.     case IME_RS_NEST: t_char="IME_RS_NEST";break;
  85.     case IME_RS_NOIME: t_char="IME_RS_NOIME";break;
  86.     case IME_RS_NOROOM: t_char="IME_RS_NOROOM";break;
  87.     case IME_RS_NOTFOUND: t_char="IME_RS_NOTFOUND";break;
  88.     case IME_RS_SYSTEMMODAL: t_char="IME_RS_SYSTEMMODAL";break;
  89.     case IME_RS_TOOLONG: t_char="IME_RS_TOOLONG";break;
  90.     case 0:t_char="SUCCESS";break;
  91.     default:
  92.         {
  93.             return;
  94.         }
  95.     }
  96.     g_buffers[g_numbuffers++]=(char *)t_char;
  97. }
  98. #endif //0
  99. #endif //XP_WIN16
  100. #endif //_DEBUG
  101.  
  102. #ifdef XP_WIN32
  103. #include "shlobj.h"
  104. #endif
  105.  
  106. #ifdef _DEBUG
  107. #undef THIS_FILE
  108. static char BASED_CODE THIS_FILE[] = __FILE__;
  109. #endif
  110.  
  111.  
  112. // Index to start of TrueType fonts in a menu
  113. #define ID_FORMAT_TRUETYPE_BASE ID_FORMAT_FONTFACE_BASE+2
  114.  
  115.  
  116. #ifdef _IMAGE_CONVERT
  117. #include "libcnv.h"
  118. #include "jinclude.h"
  119. #include "jpeglib.h"
  120.  
  121. UINT CNetscapeEditView::m_converrmsg[NUM_CONVERR]={
  122.     IDS_CONVERR0,//"Canceled",
  123.     IDS_CONVERR1,//"Ok",
  124.     IDS_CONVERR2,//"Invalid Source",
  125.     IDS_CONVERR3,//"Invalid Destination",
  126.     IDS_CONVERR4,//"Invalid File Header",
  127.     IDS_CONVERR5,//"Invalid Image Header",
  128.     IDS_CONVERR6,//"Invalid Bit Depth",
  129.     IDS_CONVERR7,//"Bad Read",
  130.     IDS_CONVERR8,//"Out of Memory",
  131.     IDS_CONVERR9,//"JPEG Creation Error",
  132.     IDS_CONVERR10,//"JPEG Compression Error",
  133.     IDS_CONVERR11,//"Bad Number of Bit Planes in Source",
  134.     IDS_CONVERR12,//"Writing to file failed",
  135.     IDS_CONVERR13,//"Invalid parameters to convert",
  136.     IDS_CONVERR14,//"Unknown Error"
  137. };
  138.  
  139.  
  140.  
  141. struct PluginHookStruct //this is used for the callbacks from plugins you must
  142. {                       //free the outputimagecontext yourself
  143.     MWContext *m_pMWContext;
  144.     CONVERT_IMGCONTEXT *m_outputimagecontext;
  145. };
  146.  
  147. void FE_ImageConvertPluginCallback(EDT_ImageEncoderStatus status, void* hook);
  148.  
  149. #define DEFAULT_IMG_CONVERT_QUALITY 75
  150. #define EDTMAXCOLORVALUE 256
  151.  
  152.  
  153. #endif //_IMAGE_CONVERT
  154.  
  155. // editor plugin info. this is the structure of the array elements stored in m_pPluginInfo.
  156. typedef struct _PluginInfo
  157. {
  158.     uint32  CategoryId;
  159.     uint32  PluginId;
  160. }   PluginInfo;
  161.  
  162. // implemented in edframe.cpp.  I changed this to be WFE_FindMenu in winproto.h SP 4/3/97
  163. //int FindMenu(CMenu *pMenu, CString& menuItemName);
  164.  
  165. // We do this alot
  166. #define GET_MWCONTEXT  (GetContext() == NULL ? NULL : GetContext()->GetContext())
  167.  
  168. // This is TRUE only if we have a context and are not an Editor or 
  169. //   we are an editor that has a good buffer and is not blocked 
  170. #define CAN_INTERACT  (GetContext() != NULL && GetContext()->GetContext() != NULL \
  171.                        && !GetContext()->GetContext()->waitingMode \
  172.                        && (!EDT_IS_EDITOR(GetContext()->GetContext()) \
  173.                            || (EDT_HaveEditBuffer(GetContext()->GetContext()) && !EDT_IsBlocked(GetContext()->GetContext()))))
  174.  
  175. extern char *EDT_NEW_DOC_URL;
  176. extern char *EDT_NEW_DOC_NAME;
  177.  
  178. // check if a given menu id is one of the character encoding menus
  179. BOOL IsEncodingMenu(UINT nID)
  180. {
  181.     return (nID >= ID_OPTIONS_ENCODING_1 && nID <= ID_OPTIONS_ENCODING_70 );
  182. }
  183.  
  184.  
  185. /////////////////////////////////////////////////////////////////////////////
  186. // CNetscapeEditView
  187.  
  188. #undef new
  189. IMPLEMENT_DYNCREATE(CNetscapeEditView, CNetscapeView)
  190. #define new DEBUG_NEW
  191.  
  192. // These were initially in CEditFrame:
  193. BEGIN_MESSAGE_MAP(CNetscapeEditView, CNetscapeView)
  194.     //{{AFX_MSG_MAP(CNetscapeEditView)
  195.     ON_WM_SETFOCUS()
  196.     ON_WM_KILLFOCUS()
  197.     ON_WM_CREATE()
  198.     ON_WM_CLOSE()
  199.     ON_WM_KEYDOWN()
  200.     ON_WM_CHAR()
  201.     ON_WM_TIMER()
  202.     ON_WM_LBUTTONDBLCLK()
  203.     ON_WM_RBUTTONDOWN()
  204.     ON_WM_LBUTTONUP()
  205.     ON_CBN_SELENDOK(ID_COMBO_PARA, OnSelendokParagraphCombo)
  206.     ON_CBN_SELENDOK(ID_COMBO_FONTFACE, OnSelendokFontFaceCombo)
  207.     ON_CBN_SELENDOK(ID_COMBO_FONTSIZE, OnSelendokFontSizeCombo)
  208.     ON_CBN_SELENDCANCEL(ID_COMBO_PARA, OnCancelComboBox)
  209.     ON_COMMAND(ID_OTHER_FONTFACE, OnSetLocalFontFace)
  210.     ON_COMMAND(ID_REMOVE_FONTFACE, OnRemoveFontFace)
  211.     ON_CBN_SELENDCANCEL(ID_COMBO_FONTFACE, OnCancelComboBox)
  212.     ON_CBN_SELENDCANCEL(ID_COMBO_FONTSIZE, OnCancelComboBox)
  213.     ON_COMMAND(ID_FORMAT_INCREASE_FONTSIZE, OnIncreaseFontSize)
  214.     ON_COMMAND(ID_FORMAT_DECREASE_FONTSIZE, OnDecreaseFontSize)
  215.     ON_COMMAND(ID_SETFOCUS_PARA_STYLE, OnSetFocusParagraphStyle)
  216.     ON_COMMAND(ID_SETFOCUS_FONTFACE, OnSetFocusFontFace)
  217.     ON_COMMAND(ID_SETFOCUS_FONTSIZE, OnSetFocusFontSize)
  218.     ON_COMMAND(ID_GET_COLOR, OnGetFontColor)
  219.     ON_COMMAND(ID_OPEN_NAV_WINDOW, OnOpenNavigatorWindow)
  220.     ON_COMMAND(ID_EDT_FILE_SAVEAS, OnFileSaveAs)    // This replaces ID_NETSCAPE_SAVE_AS functionality
  221.     ON_COMMAND(ID_EDT_FILE_SAVE, OnFileSave)        // This is missing from browser - we add it to the File Menu
  222.     ON_COMMAND(ID_EDT_FINDREPLACE, OnEditFindReplace)
  223.     ON_COMMAND(ID_PROPS_LINK, OnLinkProperties)
  224.     ON_COMMAND(ID_INSERT_LINK, OnInsertLink)
  225.     ON_COMMAND(ID_MAKE_LINK, OnMakeLink)
  226.     ON_COMMAND(ID_REMOVE_LINKS, OnRemoveLinks)
  227.     ON_COMMAND(ID_PROPS_TARGET, OnTargetProperties)
  228.     ON_COMMAND(ID_INSERT_TARGET, OnInsertTarget)
  229.     ON_COMMAND(ID_INSERT_IMAGE, OnInsertImage)
  230.     ON_COMMAND(ID_INSERT_HRULE, OnInsertHRule)
  231.     ON_COMMAND(ID_INSERT_TAG, OnInsertTag)
  232.     ON_COMMAND(ID_PROPS_TAG, OnTagProperties)
  233.     ON_COMMAND(ID_PROPS_IMAGE, OnImageProperties)
  234.     ON_UPDATE_COMMAND_UI(ID_PROPS_IMAGE, OnUpdateImageProperties)
  235.     ON_COMMAND(ID_PROPS_HRULE, OnHRuleProperties)
  236.     ON_COMMAND(ID_PROPS_TEXT, OnTextProperties)
  237.     ON_COMMAND(ID_PROPS_PARAGRAPH, OnParagraphProperties)
  238.     ON_COMMAND(ID_PROPS_CHARACTER, OnCharacterProperties)
  239.     ON_COMMAND(ID_PROPS_DOCUMENT, OnDocumentProperties)
  240.     ON_COMMAND(ID_PROPS_DOC_COLOR, OnDocColorProperties)
  241.     ON_UPDATE_COMMAND_UI(ID_PROPS_DOCUMENT, HaveEditContext)
  242.     ON_COMMAND(ID_FORMAT_CHAR_NO_TEXT_STYLES, OnCharacterNoTextStyles)
  243.     ON_COMMAND(ID_FORMAT_CHAR_NONE, OnCharacterNone)
  244.     ON_COMMAND(ID_FORMAT_CHAR_NONE, OnCharacterNoTextStyles)
  245.     ON_COMMAND(ID_FORMAT_CHAR_BOLD, OnCharacterBold)
  246.     ON_COMMAND(IDC_FONT_FIXED_WIDTH, OnCharacterFixedWidth)
  247.     ON_COMMAND(ID_FORMAT_CHAR_ITALIC, OnCharacterItalic)
  248.     ON_COMMAND(ID_FORMAT_CHAR_NOBREAKS, OnCharacterNoBreaks)
  249.     ON_COMMAND(ID_FORMAT_CHAR_UNDERLINE, OnCharacterUnderline)
  250.     ON_COMMAND(ID_FORMAT_CHAR_SUPER, OnCharacterSuper)
  251.     ON_COMMAND(ID_FORMAT_CHAR_SUB, OnCharacterSub)
  252.     ON_COMMAND(ID_FORMAT_CHAR_STRIKEOUT, OnCharacterStrikeout)
  253.     ON_COMMAND(ID_FORMAT_CHAR_BLINK, OnCharacterBlink)
  254.     ON_COMMAND(ID_FORMAT_INDENT, OnFormatIndent)
  255.     ON_COMMAND(ID_FORMAT_OUTDENT, OnFormatOutdent)
  256.     ON_COMMAND(ID_ALIGN_POPUP, OnAlignPopup)
  257.     ON_COMMAND(ID_INSERT_POPUP, OnInsertObjectPopup)
  258.     ON_COMMAND(ID_ALIGN_CENTER, OnAlignCenter)
  259.     ON_COMMAND(ID_ALIGN_LEFT, OnAlignLeft)
  260.     ON_COMMAND(ID_ALIGN_RIGHT, OnAlignRight)
  261.     ON_COMMAND(ID_PROPS_LOCAL,OnLocalProperties)
  262.     ON_COMMAND(ID_INSERT_LINE_BREAK,OnInsertLineBreak)
  263.     ON_COMMAND(ID_INSERT_BREAK_LEFT,OnInsertBreakLeft)
  264.     ON_COMMAND(ID_INSERT_BREAK_RIGHT,OnInsertBreakRight)
  265.     ON_COMMAND(ID_INSERT_BREAK_BOTH,OnInsertBreakBoth)
  266.     ON_COMMAND(ID_INSERT_NONBREAK_SPACE,OnInsertNonbreakingSpace)
  267.     ON_COMMAND(ID_REMOVE_LIST, OnRemoveList)
  268.     ON_COMMAND(ID_UNUM_LIST, OnUnumList)
  269.     ON_COMMAND(ID_NUM_LIST, OnNumList)
  270.     ON_COMMAND(ID_BLOCK_QUOTE, OnBlockQuote)
  271.     ON_COMMAND(ID_EDIT_SELECTALL, OnSelectAll)
  272.     ON_COMMAND(ID_EDIT_UNDO, OnUndo)
  273.     ON_COMMAND(    ID_FILE_PUBLISH, OnPublish)
  274.     ON_COMMAND(ID_EDIT_DISPLAY_PARAGRAPH_MARKS, OnDisplayParagraphMarks)
  275.     ON_COMMAND(ID_ALIGN_TABLE_LEFT, OnAlignTableLeft)
  276.     ON_COMMAND(ID_ALIGN_TABLE_CENTER, OnAlignTableCenter)
  277.     ON_COMMAND(ID_ALIGN_TABLE_RIGHT, OnAlignTableRight)
  278.     ON_COMMAND(ID_SELECT_TABLE, OnSelectTable)
  279.     ON_COMMAND(ID_SELECT_TABLE_ROW, OnSelectTableRow)
  280.     ON_COMMAND(ID_SELECT_TABLE_COLUMN, OnSelectTableColumn)
  281.     ON_COMMAND(ID_SELECT_TABLE_CELL, OnSelectTableCell)
  282.     ON_COMMAND(ID_SELECT_TABLE_ALL_CELLS, OnSelectTableAllCells)
  283.     ON_COMMAND(ID_MERGE_TABLE_CELLS, OnMergeTableCells)
  284.     ON_COMMAND(ID_SPLIT_TABLE_CELL, OnSplitTableCell)
  285.     ON_COMMAND(ID_TABLE_TEXT_CONVERT, OnTableTextConvert)
  286.     ON_COMMAND(ID_INSERT_TABLE,OnInsertTable)
  287.     ON_COMMAND(ID_INSERT_TABLE_OR_PROPS,OnInsertTableOrTableProps)
  288.     ON_COMMAND(ID_INSERT_TABLE_ROW,OnInsertTableRow)
  289.     ON_COMMAND(ID_INSERT_TABLE_ROW_ABOVE,OnInsertTableRowAbove)
  290.     ON_COMMAND(ID_INSERT_TABLE_COLUMN,OnInsertTableColumn)
  291.     ON_COMMAND(ID_INSERT_TABLE_COLUMN_BEFORE,OnInsertTableColumnBefore)
  292.     ON_COMMAND(ID_INSERT_TABLE_CELL,OnInsertTableCell)
  293.     ON_COMMAND(ID_INSERT_TABLE_CELL_BEFORE,OnInsertTableCellBefore)
  294.     ON_COMMAND(ID_INSERT_TABLE_CAPTION,OnInsertTableCaption)
  295.     ON_COMMAND(ID_DELETE_TABLE,OnDeleteTable)
  296.     ON_COMMAND(ID_DELETE_TABLE_ROW,OnDeleteTableRow)
  297.     ON_COMMAND(ID_DELETE_TABLE_COLUMN,OnDeleteTableColumn)
  298.     ON_COMMAND(ID_DELETE_TABLE_CELL,OnDeleteTableCell)
  299.     ON_COMMAND(ID_DELETE_TABLE_CAPTION,OnDeleteTableCaption)
  300.     ON_COMMAND(ID_TOGGLE_TABLE_BORDER,OnToggleTableBorder)
  301.     ON_COMMAND(ID_TOGGLE_HEADER_CELL,OnToggleHeaderCell)
  302.     ON_COMMAND(ID_PROPS_TABLE,OnPropsTable)
  303.     ON_COMMAND(ID_PROPS_TABLE_ROW,OnPropsTableRow)
  304.     ON_COMMAND(ID_PROPS_TABLE_COLUMN,OnPropsTableColumn)
  305.     ON_COMMAND(ID_PROPS_TABLE_CELL,OnPropsTableCell)
  306.     ON_COMMAND(ID_DISPLAY_TABLES, OnDisplayTables)
  307.     // Browser handles this in CAbstractCX, but editor will do stuff here
  308.     ON_COMMAND(ID_EDIT_CUT, OnEditCut)
  309.     ON_COMMAND(ID_EDIT_PASTE, OnEditPaste)
  310.     ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
  311.     ON_COMMAND(ID_COPY_STYLE, OnCopyStyle)
  312.     ON_COMMAND(ID_EDIT_DELETE, OnEditDelete)
  313.     ON_COMMAND(ID_EDIT_FINDAGAIN, OnEditFindAgain)
  314.     ON_COMMAND( ID_EDITOR_PAGEUP, OnPageUp )
  315.     ON_COMMAND( ID_EDITOR_PAGEDOWN, OnPageDown )
  316.     ON_COMMAND( ID_EDITOR_SELECTPAGEUP, OnSelectPageUp )
  317.     ON_COMMAND( ID_EDITOR_SELECTPAGEDOWN, OnSelectPageDown )
  318.     ON_COMMAND( ID_FILE_EDITSOURCE, OnEditSource)
  319.     ON_COMMAND( ID_GO_PUBLISH_LOCATION, OnGoToDefaultPublishLocation)
  320.     ON_COMMAND( ID_MAKE_IMAGE_BACKGROUND, OnSetImageAsBackground)
  321.     ON_CBN_DROPDOWN(ID_COMBO_FONTSIZE, OnFontSizeDropDown)
  322.     ON_COMMAND(ID_OPT_EDITBAR_TOGGLE, OnEditBarToggle)
  323.     ON_COMMAND(ID_OPT_CHARBAR_TOGGLE, OnCharacterBarToggle)
  324.     ON_UPDATE_COMMAND_UI(ID_OPT_EDITBAR_TOGGLE, OnUpdateEditBarToggle)
  325.     ON_UPDATE_COMMAND_UI(ID_OPT_CHARBAR_TOGGLE, OnUpdateCharacterBarToggle)
  326.     ON_COMMAND(ID_SELECT_NEXT_NONTEXT, OnSelectNextNonTextObject)
  327.     //}}AFX_MSG_MAP
  328.     // Put update commands here so we can remove them temporarily for overhead assesments
  329.     ON_UPDATE_COMMAND_UI(ID_FORMAT_INCREASE_FONTSIZE, OnUpdateIncreaseFontSize)
  330.     ON_UPDATE_COMMAND_UI(ID_FORMAT_DECREASE_FONTSIZE, OnUpdateDecreaseFontSize)
  331.     ON_UPDATE_COMMAND_UI(ID_COMBO_PARA, OnUpdateParagraphComboBox)
  332.     ON_UPDATE_COMMAND_UI(ID_COMBO_FONTFACE, OnUpdateFontFaceComboBox)
  333.     ON_UPDATE_COMMAND_UI(ID_COMBO_FONTSIZE, OnUpdateFontSizeComboBox)
  334.     ON_UPDATE_COMMAND_UI(ID_COMBO_FONTCOLOR, OnUpdateFontColorComboBox)
  335.     ON_UPDATE_COMMAND_UI(ID_REMOVE_FONTFACE,  HaveEditContext)
  336.     ON_UPDATE_COMMAND_UI(ID_PROPS_LINK, OnUpdateLinkProperties)
  337.     ON_UPDATE_COMMAND_UI(ID_INSERT_LINK, OnUpdateInsertLink)
  338.     ON_UPDATE_COMMAND_UI(ID_MAKE_LINK, HaveEditContext)
  339.     ON_UPDATE_COMMAND_UI(ID_REMOVE_LINKS, OnUpdateRemoveLinks)
  340.     ON_UPDATE_COMMAND_UI(ID_PROPS_TARGET, OnUpdateTargetProperties)
  341.     ON_UPDATE_COMMAND_UI(ID_INSERT_TARGET, HaveEditContext)
  342.     ON_UPDATE_COMMAND_UI(ID_PROPS_TARGET, HaveEditContext)
  343.     ON_UPDATE_COMMAND_UI(ID_INSERT_IMAGE, HaveEditContext)
  344.     ON_UPDATE_COMMAND_UI(ID_INSERT_HRULE, HaveEditContext)
  345.     ON_UPDATE_COMMAND_UI(ID_INSERT_TAG, HaveEditContext)
  346.     ON_UPDATE_COMMAND_UI(ID_PROPS_TAG, OnUpdateTagProperties)
  347.     ON_UPDATE_COMMAND_UI(ID_PROPS_HRULE, OnUpdateHRuleProperties)
  348.     ON_UPDATE_COMMAND_UI(ID_PROPS_TEXT, HaveEditContext)
  349.     ON_UPDATE_COMMAND_UI(ID_PROPS_PARAGRAPH, HaveEditContext)
  350.     ON_UPDATE_COMMAND_UI(ID_PROPS_CHARACTER, HaveEditContext)
  351.     ON_UPDATE_COMMAND_UI(ID_PROPS_DOC_COLOR, HaveEditContext)
  352.     ON_UPDATE_COMMAND_UI(ID_FORMAT_CHAR_NONE, OnCanInteract)     
  353.     ON_UPDATE_COMMAND_UI(ID_FORMAT_CHAR_BOLD, OnUpdateCharacterBold)          
  354.     ON_UPDATE_COMMAND_UI(ID_FORMAT_CHAR_ITALIC, OnUpdateCharacterItalic)      
  355.     ON_UPDATE_COMMAND_UI(ID_FORMAT_CHAR_NOBREAKS, OnUpdateCharacterNoBreaks)   
  356.     ON_UPDATE_COMMAND_UI(ID_FORMAT_CHAR_UNDERLINE, OnUpdateCharacterUnderline)
  357.     ON_UPDATE_COMMAND_UI(ID_FORMAT_CHAR_SUPER, OnUpdateCharacterSuper)        
  358.     ON_UPDATE_COMMAND_UI(ID_FORMAT_CHAR_SUB, OnUpdateCharacterSub)            
  359.     ON_UPDATE_COMMAND_UI(ID_FORMAT_CHAR_STRIKEOUT, OnUpdateCharacterStrikeout)
  360.     ON_UPDATE_COMMAND_UI(ID_FORMAT_CHAR_BLINK, OnUpdateCharacterBlink)        
  361.     ON_UPDATE_COMMAND_UI(ID_FORMAT_INDENT, HaveEditContext)
  362.     ON_UPDATE_COMMAND_UI(ID_FORMAT_OUTDENT, HaveEditContext)
  363.     ON_UPDATE_COMMAND_UI(ID_ALIGN_POPUP, HaveEditContext)
  364.     ON_UPDATE_COMMAND_UI(ID_PROPS_LOCAL, OnUpdatePropsLocal)
  365.     ON_UPDATE_COMMAND_UI(ID_INSERT_POPUP, HaveEditContext)
  366.     ON_UPDATE_COMMAND_UI(ID_ALIGN_CENTER, HaveEditContext)
  367.     ON_UPDATE_COMMAND_UI(ID_ALIGN_LEFT, OnUpdateAlignLeft)
  368.     ON_UPDATE_COMMAND_UI(ID_ALIGN_RIGHT, HaveEditContext)
  369.     ON_UPDATE_COMMAND_UI(ID_INSERT_LINE_BREAK, OnUpdateInsertBreak)
  370.     ON_UPDATE_COMMAND_UI(ID_INSERT_BREAK_LEFT, OnUpdateInsertBreak)
  371.     ON_UPDATE_COMMAND_UI(ID_INSERT_BREAK_RIGHT, OnUpdateInsertBreak)
  372.     ON_UPDATE_COMMAND_UI(ID_INSERT_BREAK_BOTH, OnUpdateInsertBreak)
  373.     ON_UPDATE_COMMAND_UI(ID_REMOVE_LIST, OnUpdateRemoveList)
  374.     ON_UPDATE_COMMAND_UI(ID_UNUM_LIST, OnUpdateUnumList)
  375.     ON_UPDATE_COMMAND_UI(ID_NUM_LIST, OnUpdateNumList)
  376.     ON_UPDATE_COMMAND_UI(ID_EDIT_SELECTALL, HaveEditContext)
  377.     ON_UPDATE_COMMAND_UI(ID_EDIT_UNDO, OnUpdateUndo)
  378.     ON_UPDATE_COMMAND_UI(ID_FILE_PUBLISH, HaveEditContext)
  379.     ON_UPDATE_COMMAND_UI(ID_EDIT_DISPLAY_PARAGRAPH_MARKS, OnUpdateDisplayParagraphMarks)
  380.     ON_UPDATE_COMMAND_UI(ID_ALIGN_TABLE_LEFT, OnUpdateInTable)
  381.     ON_UPDATE_COMMAND_UI(ID_ALIGN_TABLE_RIGHT, OnUpdateInTable)
  382.     ON_UPDATE_COMMAND_UI(ID_ALIGN_TABLE_CENTER, OnUpdateInTable)
  383.     ON_UPDATE_COMMAND_UI(ID_SELECT_TABLE, OnUpdateInTable)
  384.     ON_UPDATE_COMMAND_UI(ID_SELECT_TABLE_ROW, OnUpdateInTableRow)
  385.     ON_UPDATE_COMMAND_UI(ID_SELECT_TABLE_COLUMN, OnUpdateInTableColumn)
  386.     ON_UPDATE_COMMAND_UI(ID_SELECT_TABLE_CELL, OnUpdateInTableCell)
  387.     ON_UPDATE_COMMAND_UI(ID_SELECT_TABLE_ALL_CELLS, OnUpdateInTableCell)
  388.     ON_UPDATE_COMMAND_UI(ID_MERGE_TABLE_CELLS, OnUpdateMergeTableCells)
  389.     ON_UPDATE_COMMAND_UI(ID_SPLIT_TABLE_CELL, OnUpdateSplitTableCell)
  390.     ON_UPDATE_COMMAND_UI(ID_TABLE_TEXT_CONVERT, OnUpdateTableTextConvert)
  391.     ON_UPDATE_COMMAND_UI(ID_INSERT_TABLE, OnUpdateInsertTable)
  392.     ON_UPDATE_COMMAND_UI(ID_INSERT_TABLE_ROW, OnUpdateInsertTableRow)
  393.     ON_UPDATE_COMMAND_UI(ID_INSERT_TABLE_ROW_ABOVE, OnUpdateInsertTableRow)
  394.     ON_UPDATE_COMMAND_UI(ID_INSERT_TABLE_CELL, OnUpdateInsertTableCell)
  395.     ON_UPDATE_COMMAND_UI(ID_INSERT_TABLE_CELL_BEFORE, OnUpdateInsertTableCell)
  396.     ON_UPDATE_COMMAND_UI(ID_INSERT_TABLE_COLUMN, OnUpdateInsertTableColumn)
  397.     ON_UPDATE_COMMAND_UI(ID_INSERT_TABLE_COLUMN_BEFORE, OnUpdateInsertTableColumn)
  398.     ON_UPDATE_COMMAND_UI(ID_INSERT_TABLE_CAPTION, OnUpdateInsertTableCaption)
  399.     ON_UPDATE_COMMAND_UI(ID_DELETE_TABLE, OnUpdateInTable)
  400.     ON_UPDATE_COMMAND_UI(ID_DELETE_TABLE_ROW, OnUpdateInTableRow)
  401.     ON_UPDATE_COMMAND_UI(ID_DELETE_TABLE_COLUMN, OnUpdateInTableColumn)
  402.     ON_UPDATE_COMMAND_UI(ID_DELETE_TABLE_CELL, OnUpdateInTableCell)
  403.     ON_UPDATE_COMMAND_UI(ID_DELETE_TABLE_CAPTION, OnUpdateInTableCaption)
  404.     ON_UPDATE_COMMAND_UI(ID_TOGGLE_TABLE_BORDER, OnUpdateToggleTableBorder)
  405.     ON_UPDATE_COMMAND_UI(ID_TOGGLE_HEADER_CELL, OnUpdateToggleHeaderCell)
  406.     ON_UPDATE_COMMAND_UI(ID_PROPS_TABLE, OnUpdateInTable)
  407.     ON_UPDATE_COMMAND_UI(ID_PROPS_TABLE_ROW, OnUpdateInTableRow)
  408.     ON_UPDATE_COMMAND_UI(ID_PROPS_TABLE_COLUMN, OnUpdateInTableColumn)
  409.     ON_UPDATE_COMMAND_UI(ID_PROPS_TABLE_CELL, OnUpdateInTableCell)
  410.     ON_UPDATE_COMMAND_UI(ID_DISPLAY_TABLES, OnUpdateDisplayTables)
  411.     ON_UPDATE_COMMAND_UI(ID_EDIT_COPY, OnUpdateEditCopy)
  412.     ON_UPDATE_COMMAND_UI(ID_COPY_STYLE, OnUpdateCopyStyle)
  413.     ON_UPDATE_COMMAND_UI(ID_EDIT_CUT, OnUpdateEditCut)
  414.     ON_UPDATE_COMMAND_UI(ID_EDIT_DELETE, OnCanInteract)
  415.     ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE, OnUpdateEditPaste)
  416.     ON_UPDATE_COMMAND_UI(ID_LOCAL_POPUP, OnCanInteract)
  417.     ON_UPDATE_COMMAND_UI(ID_FILE_EDITSOURCE, OnCanInteract)
  418.     ON_UPDATE_COMMAND_UI(ID_GO_PUBLISH_LOCATION, OnCanInteract)
  419.     // Paragraph tags cover whole range starting from P_TEXT (=0),
  420.     //  but "Normal" is first menu item (tag = P_PARAGRAPH)
  421.     ON_UPDATE_COMMAND_UI((ID_FORMAT_PARAGRAPH_BASE+P_NSDT), OnUpdateParagraphMenu)
  422.     ON_UPDATE_COMMAND_UI((ID_FORMAT_PARAGRAPH_BASE+P_HEADER_1), OnUpdateParagraphMenu)
  423.     ON_UPDATE_COMMAND_UI((ID_FORMAT_PARAGRAPH_BASE+P_HEADER_2), OnUpdateParagraphMenu)
  424.     ON_UPDATE_COMMAND_UI((ID_FORMAT_PARAGRAPH_BASE+P_HEADER_3), OnUpdateParagraphMenu)
  425.     ON_UPDATE_COMMAND_UI((ID_FORMAT_PARAGRAPH_BASE+P_HEADER_4), OnUpdateParagraphMenu)
  426.     ON_UPDATE_COMMAND_UI((ID_FORMAT_PARAGRAPH_BASE+P_HEADER_5), OnUpdateParagraphMenu)
  427.     ON_UPDATE_COMMAND_UI((ID_FORMAT_PARAGRAPH_BASE+P_HEADER_6), OnUpdateParagraphMenu)
  428.     ON_UPDATE_COMMAND_UI((ID_FORMAT_PARAGRAPH_BASE+P_PARAGRAPH), OnUpdateParagraphMenu)
  429.     ON_UPDATE_COMMAND_UI((ID_FORMAT_PARAGRAPH_BASE+P_DESC_TEXT), OnUpdateParagraphMenu)
  430.     ON_UPDATE_COMMAND_UI((ID_FORMAT_PARAGRAPH_BASE+P_ADDRESS), OnUpdateParagraphMenu)
  431.     ON_UPDATE_COMMAND_UI((ID_FORMAT_PARAGRAPH_BASE+P_PREFORMAT), OnUpdateParagraphMenu)
  432.     ON_UPDATE_COMMAND_UI((ID_FORMAT_PARAGRAPH_BASE+P_DESC_TITLE), OnUpdateParagraphMenu)
  433.     ON_UPDATE_COMMAND_UI((ID_FORMAT_PARAGRAPH_BASE+P_BLOCKQUOTE), OnUpdateParagraphMenu)
  434.     ON_UPDATE_COMMAND_UI((ID_FORMAT_FONTSIZE_BASE), OnUpdateFontSizeMenu)
  435.     ON_UPDATE_COMMAND_UI((ID_FORMAT_FONTSIZE_BASE+1), OnUpdateFontSizeMenu)
  436.     ON_UPDATE_COMMAND_UI((ID_FORMAT_FONTSIZE_BASE+2), OnUpdateFontSizeMenu)
  437.     ON_UPDATE_COMMAND_UI((ID_FORMAT_FONTSIZE_BASE+3), OnUpdateFontSizeMenu)
  438.     ON_UPDATE_COMMAND_UI((ID_FORMAT_FONTSIZE_BASE+4), OnUpdateFontSizeMenu)
  439.     ON_UPDATE_COMMAND_UI((ID_FORMAT_FONTSIZE_BASE+5), OnUpdateFontSizeMenu)
  440.     ON_UPDATE_COMMAND_UI((ID_FORMAT_FONTSIZE_BASE+6), OnUpdateFontSizeMenu)
  441. #ifdef _IME_COMPOSITION
  442.     ON_WM_LBUTTONDOWN()
  443.     #ifdef WIN32
  444.     ON_MESSAGE(WM_IME_COMPOSITION,CNetscapeEditView::OnWmeImeComposition)
  445.     ON_MESSAGE(WM_IME_STARTCOMPOSITION,CNetscapeEditView::OnWmeImeStartComposition)
  446.     ON_MESSAGE(WM_IME_ENDCOMPOSITION,CNetscapeEditView::OnWmeImeEndComposition)
  447.     ON_MESSAGE(WM_IME_KEYDOWN,CNetscapeEditView::OnWmeImeKeyDown)
  448.     ON_MESSAGE(WM_INPUTLANGCHANGE,CNetscapeEditView::OnInputLanguageChange)
  449.     ON_MESSAGE(WM_INPUTLANGCHANGEREQUEST,CNetscapeEditView::OnInputLanguageChangeRequest)
  450.     #else //win16
  451.     ON_MESSAGE(WM_IME_REPORT,CNetscapeEditView::OnReportIme)
  452.     #endif //WIN32
  453. #endif //_IME_COMPOSITION
  454.     ON_MESSAGE(NSBUTTONMENUOPEN, OnButtonMenuOpen)
  455.     ON_COMMAND((ID_FORMAT_FONTSIZE_BASE),   OnFontSize_2)
  456.     ON_COMMAND((ID_FORMAT_FONTSIZE_BASE+1), OnFontSize_1)
  457.     ON_COMMAND((ID_FORMAT_FONTSIZE_BASE+2), OnFontSize0)
  458.     ON_COMMAND((ID_FORMAT_FONTSIZE_BASE+3), OnFontSize1)
  459.     ON_COMMAND((ID_FORMAT_FONTSIZE_BASE+4), OnFontSize2)
  460.     ON_COMMAND((ID_FORMAT_FONTSIZE_BASE+5), OnFontSize3)
  461.     ON_COMMAND((ID_FORMAT_FONTSIZE_BASE+6), OnFontSize4)
  462.     ON_COMMAND(ID_FORMAT_POINTSIZE_BASE, OnPointSize8)
  463.     ON_COMMAND((ID_FORMAT_POINTSIZE_BASE+1), OnPointSize9)
  464.     ON_COMMAND((ID_FORMAT_POINTSIZE_BASE+2), OnPointSize10)
  465.     ON_COMMAND((ID_FORMAT_POINTSIZE_BASE+3), OnPointSize11)
  466.     ON_COMMAND((ID_FORMAT_POINTSIZE_BASE+4), OnPointSize12)
  467.     ON_COMMAND((ID_FORMAT_POINTSIZE_BASE+5), OnPointSize14)
  468.     ON_COMMAND((ID_FORMAT_POINTSIZE_BASE+6), OnPointSize16)
  469.     ON_COMMAND((ID_FORMAT_POINTSIZE_BASE+7), OnPointSize18)
  470.     ON_COMMAND((ID_FORMAT_POINTSIZE_BASE+8), OnPointSize20)
  471.     ON_COMMAND((ID_FORMAT_POINTSIZE_BASE+9), OnPointSize22)
  472.     ON_COMMAND((ID_FORMAT_POINTSIZE_BASE+10), OnPointSize24)
  473.     ON_COMMAND((ID_FORMAT_POINTSIZE_BASE+11), OnPointSize28)
  474.     ON_COMMAND((ID_FORMAT_POINTSIZE_BASE+12), OnPointSize36)
  475.     ON_COMMAND((ID_FORMAT_POINTSIZE_BASE+13), OnPointSize48)
  476.     ON_COMMAND((ID_FORMAT_POINTSIZE_BASE+14), OnPointSize72)
  477.     ON_UPDATE_COMMAND_UI(ID_FORMAT_POINTSIZE_BASE, HaveEditContext)
  478.     ON_UPDATE_COMMAND_UI((ID_FORMAT_POINTSIZE_BASE+1), HaveEditContext)
  479.     ON_UPDATE_COMMAND_UI((ID_FORMAT_POINTSIZE_BASE+2), HaveEditContext)
  480.     ON_UPDATE_COMMAND_UI((ID_FORMAT_POINTSIZE_BASE+3), HaveEditContext)
  481.     ON_UPDATE_COMMAND_UI((ID_FORMAT_POINTSIZE_BASE+4), HaveEditContext)
  482.     ON_UPDATE_COMMAND_UI((ID_FORMAT_POINTSIZE_BASE+5), HaveEditContext)
  483.     ON_UPDATE_COMMAND_UI((ID_FORMAT_POINTSIZE_BASE+6), HaveEditContext)
  484.     ON_UPDATE_COMMAND_UI((ID_FORMAT_POINTSIZE_BASE+7), HaveEditContext)
  485.     ON_UPDATE_COMMAND_UI((ID_FORMAT_POINTSIZE_BASE+8), HaveEditContext)
  486.     ON_UPDATE_COMMAND_UI((ID_FORMAT_POINTSIZE_BASE+9), HaveEditContext)
  487.     ON_UPDATE_COMMAND_UI((ID_FORMAT_POINTSIZE_BASE+10), HaveEditContext)
  488.     ON_UPDATE_COMMAND_UI((ID_FORMAT_POINTSIZE_BASE+11), HaveEditContext)
  489.     ON_UPDATE_COMMAND_UI((ID_FORMAT_POINTSIZE_BASE+12), HaveEditContext)
  490.     ON_UPDATE_COMMAND_UI((ID_FORMAT_POINTSIZE_BASE+13), HaveEditContext)
  491.     ON_UPDATE_COMMAND_UI((ID_FORMAT_POINTSIZE_BASE+14), HaveEditContext)
  492.     ON_COMMAND(ID_CHECK_SPELLING, OnCheckSpelling)
  493.     ON_UPDATE_COMMAND_UI(ID_CHECK_SPELLING, OnCanInteract)
  494.     ON_UPDATE_COMMAND_UI(ID_INSERT_NONBREAK_SPACE, OnCanInteract)
  495.     ON_UPDATE_COMMAND_UI(ID_GET_COLOR, OnCanInteract)
  496.     ON_UPDATE_COMMAND_UI(ID_EDT_FILE_SAVE, OnUpdateFileSave)
  497.     ON_UPDATE_COMMAND_UI(ID_EDT_FILE_SAVEAS, OnCanInteract)
  498.     ON_UPDATE_COMMAND_UI(ID_FILE_MAILTO, OnCanInteract)
  499.     ON_UPDATE_COMMAND_UI(ID_FILE_PUBLISH, OnCanInteract)
  500.     ON_UPDATE_COMMAND_UI(ID_FILE_PAGE_SETUP, OnCanInteract)
  501.     ON_UPDATE_COMMAND_UI(ID_FILE_PRINT_PREVIEW, OnCanInteract)
  502.     ON_UPDATE_COMMAND_UI(ID_EDIT_FINDINCURRENT, OnCanInteract)
  503.     ON_UPDATE_COMMAND_UI(ID_EDIT_FINDAGAIN, OnUpdateEditFindAgain)
  504.     ON_UPDATE_COMMAND_UI(ID_FILE_PRINT, OnCanInteract)
  505.     ON_UPDATE_COMMAND_UI(ID_FILE_PRINT, OnCanInteract)
  506.     ON_UPDATE_COMMAND_UI(ID_FILE_DOCINFO, OnUpdateFileDocinfo)
  507.     ON_UPDATE_COMMAND_UI(ID_OPEN_NAV_WINDOW, OnCanInteract)
  508. END_MESSAGE_MAP()
  509.  
  510. #define new DEBUG_NEW  // MSVC Debugging new...goes to regular new in release mode
  511.  
  512. CNetscapeEditView::CNetscapeEditView()  
  513. {
  514.     m_bIsEditor = TRUE;
  515.     m_pEditDropTarget = NULL;
  516.     m_bAutoSelectObject = FALSE;
  517.     m_nLoadingImageCount = 0;
  518.     m_pLoadingImageDlg = NULL;
  519.     m_FileSaveStatus = ED_ERROR_NONE;
  520.     
  521.     memset( (void*)&m_EditState, 0, sizeof( ED_FORMATSTATE ) );
  522.     m_EditState.nParagraphFormat = P_UNKNOWN;
  523.  
  524.     // Initialize with black
  525.     m_EditState.crFontColor = NO_COLORREF;
  526.     
  527.     m_bSaveRemoteToLocal = FALSE;
  528.  
  529.     m_nFontColorCount = 16;
  530.     m_crDefColor = RGB(0,0,0);
  531.     m_pImagePage = NULL;
  532.     m_pColorPage = NULL;
  533.  
  534.     m_caret.bEnabled = FALSE;
  535.     m_caret.cShown = 0;
  536.     m_caret.x = 0;
  537.     m_caret.y = 0;
  538.     // Initialize caret size in case we get focus before DisplayCaret is called
  539.     m_caret.width = 2;
  540.     m_caret.height = 20;
  541.  
  542.     m_bDragOver = FALSE;
  543.     m_crLastDragRect.SetRectEmpty();
  544.  
  545.     m_pPluginInfo = NULL;
  546.     m_NumPlugins = 0;
  547.     m_pime=NULL;
  548. #ifdef XP_WIN16
  549.     m_hIME=NULL;
  550. #endif
  551. #ifdef _IME_COMPOSITION
  552.     m_imebool=FALSE;
  553.     m_pchardata=NULL;
  554.     m_imeoldcursorpos= (DWORD)-1;
  555. #endif
  556.     m_pTempFilename = NULL;
  557.  
  558.     SetEditChanged();
  559. }
  560.  
  561. CNetscapeEditView::~CNetscapeEditView()  
  562. {
  563.     if(m_pEditDropTarget) {
  564.         m_pEditDropTarget->Revoke();
  565.         delete m_pEditDropTarget;
  566.         m_pEditDropTarget = NULL;
  567.     }
  568. #ifdef XP_WIN16
  569.     ImeDestroy();
  570. #endif
  571. #ifdef _IME_COMPOSITION
  572.     if (m_pime)//inline eastern input
  573.         delete m_pime;
  574.     XP_FREEIF(m_pchardata);
  575. #endif
  576.  
  577.     XP_FREEIF(m_pPluginInfo);
  578.     XP_FREEIF(m_pTempFilename);
  579. }
  580.  
  581.  
  582.  
  583.  
  584. /////////////////////////////////////////////////////////////////////////////
  585. // CNetscapeEditView diagnostics
  586.  
  587. #ifdef _DEBUG
  588. void CNetscapeEditView::AssertValid() const
  589. {
  590.     CGenericView::AssertValid();
  591. }
  592.  
  593. void CNetscapeEditView::Dump(CDumpContext& dc) const
  594. {
  595.     CGenericView::Dump(dc);
  596. }
  597. #endif //_DEBUG
  598.  
  599.  
  600.  
  601. // Layout routines call this when caret has moved and there might be 
  602. //   a change in format states
  603. void CNetscapeEditView::SetEditChanged()
  604. {
  605.     // Set flags to check if items in comboboxes need to change
  606.     m_EditState.bParaFormatMaybeChanged = TRUE;
  607.     m_EditState.bFontFaceMaybeChanged = TRUE;
  608.     m_EditState.bFontSizeMaybeChanged = TRUE;
  609.     m_EditState.bFontColorMaybeChanged = TRUE;
  610. }
  611.  
  612.  
  613. /////////////////////////////////////////////////////////////////////////////
  614. int CNetscapeEditView::OnCreate(LPCREATESTRUCT lpCreateStruct)
  615. {
  616.     // Show the Wait cursor. The cursor is restored in the destructor.
  617.     CWaitCursor WaitCursor;
  618.  
  619.     int nRetVal = CNetscapeView::OnCreate(lpCreateStruct);
  620.  
  621.     // Save our frame since we use it alot
  622.     // Do it even if we fail creating the base class 'cause we
  623.     //  might get OnUpdateCommandUI messages that use frame
  624.  
  625.     if ( nRetVal ){
  626.  
  627.         m_EditState.crFontColor = DEFAULT_COLORREF;
  628.         m_crDefColor = RGB(0,0,0);
  629.     }
  630.     // Replace the base class' drop target with ours
  631.     if(m_pDropTarget) {
  632.         m_pDropTarget->Revoke();
  633.         delete m_pDropTarget;
  634.         m_pDropTarget = NULL;
  635.     }
  636.     if(!m_pEditDropTarget) {
  637.         m_pEditDropTarget = new CEditViewDropTarget;
  638.         m_pEditDropTarget->Register(this);
  639.     }
  640. #if _IME_COMPOSITION
  641. #ifdef XP_WIN32
  642.     m_csid=CIntlWin::CodePageToCsid(GetOEMCP());
  643. #endif //XP_WIN32
  644. #endif
  645.     AddPluginMenus();
  646. #ifdef XP_WIN16
  647.     initializeIME();
  648. #endif //XP_WIN16
  649.     return nRetVal;
  650. }
  651.  
  652. // AddPluginMenus - called from OnCreate to add menu items for the loaded editor plugin modules.
  653.  
  654. void CNetscapeEditView::AddPluginMenus()
  655. {
  656.     CFrameWnd *pFrame = GetParentFrame();
  657.     ASSERT(pFrame != NULL);
  658.  
  659.     // Get the menu bar
  660.     CMenu *pMenu=pFrame->GetMenu();
  661.     if (pMenu == NULL)
  662.     {
  663.         ASSERT(FALSE);
  664.         return;
  665.     }
  666.  
  667.     // find the Tools submenu
  668.     CString MenuText;
  669.     MenuText.LoadString(IDS_TOOLS_MENU);
  670.  
  671.     CMenu   *pToolsMenu = NULL;
  672.     int     ToolsMenuPosition = WFE_FindMenu(pMenu, MenuText); 
  673.  
  674.     if (ToolsMenuPosition != -1)
  675.         pToolsMenu = pMenu->GetSubMenu(ToolsMenuPosition);
  676.  
  677.     if (pToolsMenu == NULL)
  678.     {
  679.         ASSERT(FALSE);
  680.         return;
  681.     }
  682.  
  683.     // Remove the dummy plugin menu item
  684.     if (pToolsMenu->RemoveMenu(ID_EDITOR_PLUGINS_BASE, MF_BYCOMMAND) == 0)
  685.         return;     // couldn't locate the menu item
  686.  
  687.     // Add menu ids for loaded editor plugins
  688.     int32 NumCategories = EDT_NumberOfPluginCategories();
  689.  
  690.     if (NumCategories != 0)
  691.         pToolsMenu->InsertMenu(ID_STOP_EDITOR_PLUGIN, MF_SEPARATOR, 0, (LPCTSTR)NULL);
  692.     else
  693.         pToolsMenu->RemoveMenu(ID_STOP_EDITOR_PLUGIN, MF_BYCOMMAND);
  694.  
  695.     // Create a popup menu for each plugin category
  696.     UINT MenuId = ID_EDITOR_PLUGINS_BASE;
  697.     for (int32 Cat = 0; Cat < NumCategories; Cat++)
  698.     {
  699.         char*   CatName = EDT_GetPluginCategoryName(Cat);
  700.  
  701.         if (CatName != NULL)
  702.         {
  703.             int32   NumPlugins = EDT_NumberOfPlugins(Cat);
  704.             if (NumPlugins == 0)        // category with no plugins?
  705.                 continue;
  706.  
  707.             HMENU   PopupMenu = ::CreatePopupMenu();
  708.             if (PopupMenu == NULL)
  709.             {
  710. #ifdef DEBUG
  711.                 MessageBox("Could not create popup menu for editor plugins");
  712. #endif
  713.                 return;
  714.             }
  715.  
  716.             // Add the popup menu to the Tools menu group
  717.             pToolsMenu->InsertMenu(ID_STOP_EDITOR_PLUGIN, MF_BYCOMMAND | MF_STRING | MF_POPUP, (UINT)PopupMenu, CatName);
  718.               
  719.             // Add plugin menu items to the popup menu group
  720.             for (int32 Plugin = 0; Plugin < NumPlugins; Plugin++, MenuId++)
  721.             {
  722.                 char* PluginName = EDT_GetPluginName(Cat, Plugin);
  723.                 if (PluginName != NULL)
  724.                 {
  725.                     if (MenuId < ID_EDITOR_PLUGINS_BASE + MAX_EDITOR_PLUGINS)
  726.                     {
  727.                         BOOL Status = ::AppendMenu(PopupMenu, MF_STRING, MenuId, PluginName);
  728.                         if (Status == FALSE)
  729.                         {
  730.                             ASSERT(FALSE);
  731.                             return;
  732.                         }
  733.  
  734.                         m_NumPlugins++;
  735.                         m_pPluginInfo = (PluginInfo *)XP_REALLOC(m_pPluginInfo, 
  736.                                                                  sizeof(PluginInfo) * m_NumPlugins);
  737.                         if (m_pPluginInfo == NULL)
  738.                         {
  739.                             ASSERT(FALSE);
  740.                             return;
  741.                         }
  742.                         int Index = CASTINT(MenuId - ID_EDITOR_PLUGINS_BASE);
  743.                         m_pPluginInfo[Index].CategoryId = Cat;
  744.                         m_pPluginInfo[Index].PluginId = Plugin;
  745.                     }
  746.                     else
  747.                     {
  748. #ifdef DEBUG
  749.                         MessageBox("Too many editor plugins.");
  750. #endif
  751.                         return;
  752.                     }
  753.                 }
  754.                 else
  755.                     ASSERT(FALSE);          // NULL plugin name
  756.             }
  757.             
  758.         }
  759.         else
  760.             ASSERT(FALSE);                  // NULL category name
  761.     } // for
  762. }
  763.  
  764.  
  765.  
  766. BOOL CNetscapeEditView::GetPluginInfo(UINT MenuId, uint32 *CategoryId, uint32 *PluginId)
  767. {
  768.     // Check for invalid menu id
  769.     if (MenuId < ID_EDITOR_PLUGINS_BASE || MenuId >= (ID_EDITOR_PLUGINS_BASE + m_NumPlugins))
  770.         return FALSE;
  771.  
  772.     UINT Index = CASTUINT(MenuId - ID_EDITOR_PLUGINS_BASE);
  773.     *CategoryId = m_pPluginInfo[Index].CategoryId;
  774.     *PluginId = m_pPluginInfo[Index].PluginId;
  775.     return TRUE;
  776. }
  777. /////////////////////////////////////////////////////////
  778. // Simple dialog with 2 choices -- use so buttons have
  779. //   better text than "Yes"/"No" or "OK"/"Cancel"
  780. // Used only in OnSetFocus() below
  781. class CResolveEditChangesDlg : public CDialog
  782. {
  783. // Construction
  784. public:
  785.     CResolveEditChangesDlg(CWnd * pParent = NULL);
  786.     BOOL  bUseExternalChanges;
  787.                    
  788. private:
  789.     // This will change resource hInstance to Editor dll
  790.     CEditorResourceSwitcher m_ResourceSwitcher;
  791. protected:
  792.     //{{AFX_MSG(CPublishDlg)
  793.        virtual BOOL OnInitDialog();
  794.     afx_msg void OnUseInternalChanges();
  795.     afx_msg void OnUseExternalChanges();
  796.     //}}AFX_MSG
  797.     DECLARE_MESSAGE_MAP()
  798. };
  799.  
  800. CResolveEditChangesDlg::CResolveEditChangesDlg(CWnd * pParent)
  801.     : CDialog(IDD_RESOLVE_EDIT_CHANGES, pParent),
  802.     bUseExternalChanges(FALSE)
  803. {
  804. }
  805.  
  806. BOOL CResolveEditChangesDlg::OnInitDialog() 
  807. {
  808.     // Switch back to NETSCAPE.EXE for resource hInstance
  809.     m_ResourceSwitcher.Reset();
  810.     CDialog::OnInitDialog();
  811.     return TRUE;
  812. }
  813.  
  814. BEGIN_MESSAGE_MAP(CResolveEditChangesDlg, CDialog)
  815.     //{{AFX_MSG_MAP(CResolveEditChangesDlg)
  816.     ON_BN_CLICKED(IDC_USE_INTERNAL_CHANGES, OnUseInternalChanges)
  817.     ON_BN_CLICKED(IDC_USE_EXTERNAL_CHANGES, OnUseExternalChanges)
  818.     //}}AFX_MSG_MAP
  819. END_MESSAGE_MAP()
  820.  
  821. void CResolveEditChangesDlg::OnUseInternalChanges()
  822. {
  823.     bUseExternalChanges = FALSE;
  824.     OnOK();
  825. }
  826.  
  827. void CResolveEditChangesDlg::OnUseExternalChanges()
  828. {
  829.     bUseExternalChanges = TRUE;
  830.     OnOK();
  831. }
  832. ///////////////////////////////////////////////////////
  833.  
  834. void CNetscapeEditView::OnSetFocus(CWnd *pOldWin)   
  835. {
  836.     if (m_pChild && ::IsWindow(m_pChild->m_hWnd))
  837.     {
  838.       m_pChild->SetFocus();
  839.       return;
  840.     }
  841. #ifdef MOZ_MAIL_NEWS
  842.     if (GetParentFrame()->IsKindOf(RUNTIME_CLASS(CComposeFrame)))
  843.     {
  844.         CComposeFrame * pFrame = (CComposeFrame*)GetParentFrame();
  845.         // This simply sets CComposeFrame::m_FocusField,
  846.         //  which may be a problem if we really want to return 
  847.         //  focus to previous window, such as address area
  848.         pFrame->SetFocusField(this);
  849.     }
  850. #endif // MOZ_MAIL_NEWS
  851.     CNetscapeView::OnSetFocus(pOldWin);
  852.     //TRACE2("CNetscapeEditView::OnSetFocus hCurrentFocus=%X, View=%X\n", (pOldWin ? pOldWin->m_hWnd : 0), this->m_hWnd );
  853.  
  854.     // create a caret if there is no selected text
  855.     MWContext * pMWContext = GET_MWCONTEXT;
  856.     if ( pMWContext ){
  857.         // Check if the file has been modified by an outside editor
  858.         // Reload it reload if it has. SaveAs triggers this, so check flag first
  859.         if( EDT_IsFileModified(pMWContext) ){
  860.             if( EDT_DirtyFlag(pMWContext) ){
  861.                 // In this case, there are unsaved changes in current page
  862.                 //  AND changes in the external editor's version (saved to the file)
  863.                 //  User must pick one or the other 
  864.                 CResolveEditChangesDlg dlg(GET_DLG_PARENT(this));
  865.                 dlg.DoModal();
  866.                 if( dlg.bUseExternalChanges ){
  867.                     // Load changes from the file, but
  868.                     //  we must fool editor in thinking its not dirty
  869.                     //  else we get a save prompt when loading URL
  870.                     EDT_SetDirtyFlag(pMWContext, FALSE);
  871.                     GetContext()->NiceReload();
  872.                 }
  873.                 // Note: we do NOT save the changes to file 
  874.                 //    if use rejected using the external changes
  875.             } else if( IDYES == MessageBox( szLoadString(IDS_FILE_IS_MODIFIED),
  876.                         szLoadString(IDS_FILE_MODIFIED_CAPTION),
  877.                         MB_YESNO | MB_ICONQUESTION) ){
  878.                 GetContext()->NiceReload();
  879.             }
  880.         } else if( !EDT_IsSelected(pMWContext) ){
  881.             //TRACE1( "CNetscapeEditView::OnSetFocus: Caret created and enabled. bEnable was %d\n",m_caret.bEnabled);
  882.             CreateSolidCaret(m_caret.width,m_caret.height);
  883.             SetCaretPos(CPoint(m_caret.x, m_caret.y));
  884.             ShowCaret();
  885.             m_caret.cShown = 1;
  886.             m_caret.bEnabled = TRUE;
  887.         }
  888.     }
  889. #ifdef _IME_COMPOSITION
  890.     if (m_imebool)
  891.     {    
  892.         if (m_pime)
  893.         {
  894.     #ifdef XP_WIN32
  895.             CFont *t_phfont=CFont::FromHandle((HFONT)GetStockObject(SYSTEM_FONT));
  896.             if (t_phfont)
  897.             {
  898.                 LOGFONT t_logfont;
  899.                 if (t_phfont->GetLogFont(&t_logfont))
  900.                     ImeSetFont(this->GetSafeHwnd(),&t_logfont);
  901.             }
  902.     #else
  903.     #endif //XP_WIN32 else xp_win16
  904.         }
  905.     }
  906. #ifdef XP_WIN16
  907.     initializeIME();
  908.     if (!pOldWin||(pOldWin->m_hWnd!=GetParent()->m_hWnd))
  909.     {
  910.         LPIMESTRUCT lpIme;
  911.         if (!(lpIme = (LPIMESTRUCT)GlobalLock(m_hIME)))
  912.             return;
  913.  
  914.         lpIme->fnc=IME_GETOPEN;
  915.         lpIme->wParam=0;
  916.         lpIme->lParam1=0;
  917.         lpIme->lParam2=0;
  918.         lpIme->lParam3=0;
  919.         GlobalUnlock(m_hIME);
  920.         if (m_pime->SendIMEMessageEx(this->GetSafeHwnd(),m_lIMEParam))
  921.         {
  922.             if (!(lpIme = (LPIMESTRUCT)GlobalLock(m_hIME)))
  923.                 return;
  924.             lpIme->fnc=IME_SETOPEN;
  925.             lpIme->wParam=0;
  926.             lpIme->lParam1=0;
  927.             lpIme->lParam2=0;
  928.             lpIme->lParam3=0;
  929.             GlobalUnlock(m_hIME);
  930.             m_pime->SendIMEMessageEx(this->GetSafeHwnd(),m_lIMEParam);
  931.             if (!(lpIme = (LPIMESTRUCT)GlobalLock(m_hIME)))
  932.                 return;
  933.             lpIme->fnc=IME_SETOPEN;
  934.             lpIme->wParam=1;
  935.             lpIme->lParam1=0;
  936.             lpIme->lParam2=0;
  937.             lpIme->lParam3=0;
  938.             GlobalUnlock(m_hIME);
  939.             m_pime->SendIMEMessageEx(this->GetSafeHwnd(),m_lIMEParam);
  940.         }
  941.         else
  942.             GlobalUnlock(m_hIME);
  943.     }
  944. #endif //XP_WIN16
  945. #endif //_IME_COMPOSITION
  946. }
  947.  
  948. void CNetscapeEditView::OnKillFocus(CWnd *pOldWin)  
  949. {
  950.     MWContext * pMWContext=NULL;
  951.  
  952.     //TRACE1("CNetscapeView::KillFocusEdit hOldWin=%X\n", (pOldWin ? pOldWin->GetSafeHwnd() : NULL));
  953.     if (  m_caret.bEnabled &&
  954.         GetContext() && (NULL != (pMWContext = GET_MWCONTEXT)) &&
  955.         !EDT_IsSelected(pMWContext) )
  956.     {
  957.         CPoint cPoint = GetCaretPos();
  958.         m_caret.x = cPoint.x;
  959.         m_caret.y = cPoint.y;
  960.  
  961.         DestroyCaret();
  962.         m_caret.cShown = 0;
  963.         m_caret.bEnabled = FALSE;
  964.         //TRACE0("CNetscapeEditView::OnKillFocus: Caret destroyed\n");
  965.     }
  966.     
  967. #ifdef _IME_COMPOSITION
  968.     if (m_imebool)
  969.     {    
  970.         if (m_pime)
  971.         {
  972.     #ifdef XP_WIN32
  973.             HIMC hIMC;
  974.             if (hIMC = m_pime->ImmGetContext(this->m_hWnd))
  975.             {
  976.                 m_pime->ImmNotifyIME(hIMC,NI_COMPOSITIONSTR,CPS_COMPLETE,NULL);
  977.                 m_pime->ImmReleaseContext(this->m_hWnd,hIMC);
  978.             }
  979.     #else //xp_win16
  980.             if (!pOldWin||(pOldWin->m_hWnd!=GetParent()->m_hWnd))
  981.             {
  982.                 if (!pMWContext)
  983.                     pMWContext = GET_MWCONTEXT;
  984.                 if (pMWContext)
  985.                 {
  986.                     EDT_SetInsertPointToOffset(pMWContext,m_imeoffset+m_imelength,0);
  987.                     m_pchardata->mask= -1;
  988.                     CLEARBIT(m_pchardata->values,TF_INLINEINPUT);//we are done!
  989.                     EDT_SetCharacterDataAtOffset(pMWContext,m_pchardata,m_imeoffset,m_imelength);
  990.                     m_imelength=0;
  991.                     OnImeEndComposition();
  992.                 }
  993.             }
  994.     #endif //XP_WIN32 else xp_win16
  995.         }
  996.     }
  997. #endif //_IME_COMPOSITION
  998.     // CNetscapeView doens't need this?
  999.     CNetscapeView::OnKillFocus(pOldWin);
  1000. }
  1001.  
  1002. BOOL CNetscapeEditView::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo) 
  1003. {
  1004.     // was this a windows menu selection ?
  1005.     switch (nCode)
  1006.     {
  1007.     case CN_COMMAND:
  1008.         if (nID >= ID_EDITOR_PLUGINS_BASE && nID < ID_EDITOR_PLUGINS_BASE + MAX_EDITOR_PLUGINS)
  1009.         {
  1010.             uint32 CategoryId, PluginId;
  1011.             if (GetPluginInfo(nID, &CategoryId, &PluginId))
  1012.             {
  1013.                 if (!EDT_PerformPlugin(GET_MWCONTEXT, CategoryId, PluginId, NULL, NULL))
  1014.                     MessageBox(szLoadString(IDS_ERR_LAUNCH_EDITOR_PLUGIN), NULL, MB_ICONSTOP);
  1015.                 
  1016.                 return TRUE;            // the message was handled here
  1017.             }
  1018.             ASSERT(FALSE);
  1019.         }
  1020.         else if(nID >= ID_EDIT_HISTORY_BASE && nID <= (ID_EDIT_HISTORY_BASE + MAX_EDIT_HISTORY_LOCATIONS))
  1021.         {
  1022.             char * pURL = NULL;
  1023.             if( EDT_GetEditHistory(GET_MWCONTEXT, nID-ID_EDIT_HISTORY_BASE, &pURL, NULL) )
  1024.             {
  1025.                 FE_LoadUrl(pURL, LOAD_URL_COMPOSER);
  1026.                 return TRUE;
  1027.             }
  1028.         }
  1029.         else if (nID == ID_STOP_EDITOR_PLUGIN)
  1030.         {
  1031.             EDT_StopPlugin(GET_MWCONTEXT);
  1032.             return TRUE;
  1033.         }
  1034.         // Dynamically-built font face menu items
  1035.         else if (nID >= ID_FORMAT_FONTFACE_BASE && nID < (ID_FORMAT_FONTFACE_BASE+MAX_TRUETYPE_FONTS+3))
  1036.         {
  1037.             // 0 = Variable Width, 1 = Fixed Width
  1038.             int iIndex = (nID == ID_FORMAT_FONTFACE_BASE+1) ? 1 : 0;
  1039.             char * pFace = NULL;
  1040.  
  1041.             if( nID >= ID_FORMAT_TRUETYPE_BASE){
  1042.                 // The TrueType fonts start at index = 2 in font list
  1043.                 pFace = wfe_ppTrueTypeFonts[nID - ID_FORMAT_FONTFACE_BASE-2];
  1044.             }
  1045.             // Change the font face
  1046.             EDT_SetFontFace(GET_MWCONTEXT, NULL, iIndex, pFace);
  1047.             // Trigger update of toolbar combobox
  1048.             m_EditState.bFontFaceMaybeChanged = TRUE;
  1049.             return TRUE;
  1050.         }
  1051.         else if(nID >= ID_FORMAT_PARAGRAPH_BASE && nID <= ID_FORMAT_PARAGRAPH_END)
  1052.         {
  1053.             TagType t = TagType(nID - ID_FORMAT_PARAGRAPH_BASE);
  1054.             // NOTE: P_UNUM_LIST and P_NUM_LIST should be handled here
  1055.             //       and remove separate message handlers, but not 
  1056.             //       done now (7/23/97) to avoid changing the ID 
  1057.             //       associated with these in res\editor.rc2
  1058.             if( t == P_DIRECTORY ||
  1059.                 t == P_MENU ||
  1060.                 t == P_DESC_LIST ){
  1061.                 EDT_ToggleList(GET_MWCONTEXT, t);
  1062.                 return TRUE;
  1063.             }
  1064.             OnFormatParagraph(nID);
  1065.             return TRUE;
  1066.         }
  1067.         break;
  1068.     // TODO: Do this for these ranges as well:
  1069.     //ON_COMMAND_RANGE(ID_FORMAT_FONTSIZE_BASE, ID_FORMAT_FONTSIZE_BASE+MAX_FONT_SIZE, OnFontSize)
  1070.     //ON_COMMAND_RANGE(ID_FORMAT_FONTCOLOR_BASE, ID_FORMAT_FONTCOLOR_BASE+MAX_FONT_COLOR, OnFontColorMenu)
  1071.  
  1072.     case CN_UPDATE_COMMAND_UI:
  1073.         if (!pExtra)
  1074.         {
  1075.             ASSERT(FALSE);
  1076.             break;
  1077.         }        
  1078.         CCmdUI* pCmdUI = (CCmdUI*)pExtra;
  1079.  
  1080.         if (nID >= ID_EDITOR_PLUGINS_BASE && nID < ID_EDITOR_PLUGINS_BASE + MAX_EDITOR_PLUGINS)
  1081.         {
  1082.             pCmdUI->Enable(CAN_INTERACT && !EDT_IsPluginActive(GET_MWCONTEXT));
  1083.             return TRUE;
  1084.         }
  1085.         else if(nID >= ID_EDIT_HISTORY_BASE && nID <= (ID_EDIT_HISTORY_BASE + MAX_EDIT_HISTORY_LOCATIONS))
  1086.         {
  1087.             pCmdUI->Enable(GetContext()->CanOpenUrl());
  1088.             return TRUE;
  1089.         }
  1090.         else if (nID == ID_STOP_EDITOR_PLUGIN)
  1091.         {
  1092.             pCmdUI->Enable(EDT_IsPluginActive(GET_MWCONTEXT));
  1093.             return TRUE;
  1094.         }
  1095.         else if (IsEncodingMenu(nID))
  1096.         {
  1097.             // First let the frame class check-mark the current encoding menu entry.
  1098.             CMainFrame *pFrame = (CMainFrame *)GetParentFrame();
  1099.             pFrame->OnUpdateEncoding(pCmdUI);
  1100.             // Now conditionally enable the menu entry.
  1101.             pCmdUI->Enable(CAN_INTERACT);
  1102.             return TRUE;
  1103.         }
  1104.         // Dynamically-built font face menu items
  1105.         else if (nID >= ID_FORMAT_FONTFACE_BASE && nID < (ID_FORMAT_FONTFACE_BASE+MAX_TRUETYPE_FONTS+3))
  1106.         {
  1107.             // Hopefully, the cached index is up to date!
  1108.             pCmdUI->SetCheck(nID == (UINT)(m_EditState.iFontIndex + ID_FORMAT_FONTFACE_BASE));
  1109.             pCmdUI->Enable(CAN_INTERACT);
  1110.             return TRUE;
  1111.         }
  1112.         else if( nID > ID_FORMAT_PARAGRAPH_BASE ){
  1113.             TagType t = TagType(nID - ID_FORMAT_PARAGRAPH_BASE);
  1114.             if( t == P_BLOCKQUOTE ||
  1115.                 t == P_DIRECTORY ||
  1116.                 t == P_MENU ||
  1117.                 t == P_DESC_LIST){
  1118.                 UpdateListMenuItem(pCmdUI, t);
  1119.                 return TRUE;
  1120.             }
  1121.         }
  1122.  
  1123.         break;
  1124.     }
  1125.  
  1126.     return CNetscapeView::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
  1127. }
  1128.  
  1129. BOOL CNetscapeEditView::PreTranslateMessage(MSG * pMsg)
  1130. {
  1131.     if(    pMsg->message == WM_KEYDOWN )
  1132.     {
  1133.         // Process Ctrl+equals keydown -- for some bizarre reason,
  1134.         //  we don't get an OnKeyDown call for this message
  1135.         if( pMsg->wParam == 17 )
  1136.         {
  1137.             UpdateCursor();
  1138.         }
  1139.         else if( pMsg->wParam == 187 && (GetKeyState(VK_CONTROL) & 0x8000) )
  1140.         {
  1141. #ifdef XP_WIN32
  1142.             //this is for Swedish input of a '\'  in swedish that = <CTRL>=
  1143.             HKL hKL=GetKeyboardLayout(0);//0=active thread
  1144.             int32 langid=(int32)hKL;
  1145.             langid&=0xFFFF;//we need to zero out the high order word
  1146.             if (PRIMARYLANGID((int16)langid)!=LANG_ENGLISH)
  1147.                 return CNetscapeView::PreTranslateMessage(pMsg);
  1148. #endif
  1149.             PostMessage(WM_COMMAND, ID_FORMAT_INDENT, 0);
  1150.             return TRUE;
  1151.         }
  1152.     } else if( pMsg->message == WM_KEYUP &&
  1153.                pMsg->wParam == 17 )
  1154.     {
  1155.         UpdateCursor();
  1156.     }
  1157.     return CNetscapeView::PreTranslateMessage(pMsg);
  1158. }
  1159.  
  1160. void CNetscapeEditView::UpdateCursor()
  1161. {
  1162.     POINT pt;
  1163.     GetCursorPos(&pt);
  1164.     ScreenToClient(&pt);
  1165.     // Send mouse_move message using current 
  1166.     //   mouse location to trigger changing cursor
  1167.     SendMessage(WM_MOUSEMOVE, 0, MAKELPARAM(pt.x, pt.y));  
  1168. }
  1169.  
  1170. void CNetscapeEditView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
  1171. {
  1172.     BOOL bShift = GetKeyState(VK_SHIFT) & 0x8000;
  1173.     BOOL bControl = GetKeyState(VK_CONTROL) & 0x8000;
  1174.  
  1175.     MWContext * pMWContext = GET_MWCONTEXT;
  1176.     if( pMWContext ){
  1177.         // Ignore keys if we can't interact
  1178.         if( pMWContext->waitingMode ||
  1179.             EDT_IsBlocked(pMWContext) ){
  1180.             return;
  1181.         }
  1182.         
  1183.         int iResult = EDT_COP_OK;
  1184.         switch(nChar) {
  1185.                 // For some bizarre reason (or not?),
  1186.                 //  we don't get a message on Ctrl+equals (nChar=187)
  1187.                 // We must handle that in CNetscapeEditView::PreTranslateMessage
  1188.             case 189:   //  "-" (minus) key
  1189.                 if( bControl){
  1190.                     OnFormatOutdent();
  1191.                 }
  1192.                 break;
  1193.             case 81:
  1194.                 if( bControl) {
  1195.                     TRACE0("Ctrl-Q was pressed\n");
  1196.                 } else {
  1197.                     TRACE0("Q was pressed\n");
  1198.                 }
  1199.                 break;
  1200.             case VK_ESCAPE:
  1201.                 {
  1202.                 // Cancel an Object Sizing operation
  1203.                 if( EDT_IsSizing(pMWContext) )
  1204.                     GetContext()->CancelSizing();
  1205.  
  1206.                 // Cancel copy style action
  1207.                 if( EDT_CanPasteStyle(pMWContext) )
  1208.                 {
  1209.                     EDT_PasteStyle(pMWContext, FALSE);
  1210.                     UpdateCursor();
  1211.                 }
  1212.  
  1213.                 // Continue to do other actions on Esc key
  1214.                 break;
  1215.                 }
  1216.             case VK_BACK:
  1217.                 if( EDT_COP_OK != (iResult = CASTINT(EDT_DeletePreviousChar(pMWContext))) ){
  1218.                     ReportCopyError(iResult);
  1219.                 }
  1220.                 return;
  1221.             case VK_DELETE:
  1222.                 if (bShift)
  1223.                     OnEditCut();
  1224.  
  1225.                 else if( EDT_COP_OK != (iResult = CASTINT(EDT_DeleteChar(pMWContext))) ){
  1226.                     ReportCopyError(iResult);
  1227.                 }
  1228.                 return;
  1229.  
  1230.             case VK_RETURN:
  1231.                 if (bShift)
  1232.                     OnInsertLineBreak();
  1233.                 else if (!(GetKeyState(VK_MENU) & 0x8000))      // ALT+Enter is handled thru accelerators
  1234.                     EDT_ReturnKey(pMWContext);
  1235.                 return;
  1236.  
  1237.             case VK_LEFT:
  1238.                 if (OnLeftKey(bShift, bControl))
  1239.                     return;
  1240.                 break;
  1241.  
  1242.             case VK_RIGHT:
  1243.                 if (OnRightKey(bShift, bControl))
  1244.                     return;
  1245.                 break;
  1246.  
  1247.             case VK_DOWN:
  1248.                 if (OnDownKey(bShift, bControl))
  1249.                     return;
  1250.                 break;
  1251.  
  1252.             case VK_UP:
  1253.                 if (OnUpKey(bShift, bControl))
  1254.                     return;
  1255.                 break;
  1256.  
  1257.             case VK_HOME:
  1258.                 if (OnHomeKey(bShift, bControl))
  1259.                     return;
  1260.                 break;
  1261.  
  1262.             case VK_TAB:
  1263.                 // 2nd param: TRUE = Move Forward, FALSE = back, (ONLY WHEN IN A TABLE)
  1264.                 // 3rd param: TRUE = Force tab to be spaces at all times, even in table
  1265.                 if( EDT_COP_OK != (iResult = EDT_TabKey(pMWContext, !bShift, bControl)) ){
  1266.                     ReportCopyError(iResult);
  1267.                 }
  1268.                 return;
  1269.  
  1270.             case VK_END:
  1271.                 if (OnEndKey(bShift, bControl))
  1272.                     return;
  1273.                 break;
  1274.  
  1275.             case VK_INSERT:
  1276.                 if (OnInsertKey(bShift, bControl))
  1277.                     return;
  1278.                 break;
  1279.  
  1280.             case ' ':
  1281.                 CWnd::OnKeyDown(nChar, nRepCnt, nFlags);
  1282.                 return;
  1283.         }
  1284.     }
  1285.     CNetscapeView::OnKeyDown(nChar, nRepCnt, nFlags);
  1286. }
  1287.  
  1288.  
  1289.  
  1290. void CNetscapeEditView::OnChar(UINT nChar, UINT nRepCnt, UINT nflags)
  1291. {
  1292.     // Ignore keys if we can't interact
  1293.     if( !CAN_INTERACT ){
  1294.         return;
  1295.     }
  1296.     BOOL bShift = GetKeyState(VK_SHIFT) & 0x8000;
  1297.     BOOL bControl = GetKeyState(VK_CONTROL) & 0x8000;
  1298.  
  1299.     MWContext * pMWContext = GET_MWCONTEXT;
  1300.  
  1301.     EDT_ClearTableAndCellSelection(pMWContext);
  1302.  
  1303.     // Ignore keys if we can't interact
  1304.     INTL_CharSetInfo csi = LO_GetDocumentCharacterSetInfo(pMWContext);
  1305.     int16 win_csid = INTL_GetCSIWinCSID(csi);
  1306.     
  1307.     // Ignore keys if we can't interact
  1308.     int iResult = EDT_COP_SELECTION_CROSSES_TABLE_DATA_CELL;
  1309.         // Since any key can replace a selection,
  1310.         //   we need to test for this for any key!
  1311.     switch (nChar) {
  1312.         case 22: // Ctrl+V
  1313.             OnEditPaste();
  1314.             return;
  1315.         case ' ':
  1316.         case VK_UP:
  1317.         case VK_DOWN:
  1318.         case VK_LEFT:
  1319.         case VK_RIGHT:
  1320. //            TRACE("Cursor key %x\n", nChar);
  1321.             break;
  1322.     }
  1323. #ifdef XP_WIN32
  1324.     if ((win_csid==CS_UTF8)||(win_csid==CS_UTF7))
  1325.     {
  1326.         if (nChar >=' ')//do not pass back control characters. does not get filtered like keydown does.
  1327.         {
  1328.             char characterCode[2];
  1329.             characterCode[0] = (char) nChar;
  1330.             characterCode[1] = '\0';
  1331.             unsigned char* t_unicodestring= INTL_ConvertLineWithoutAutoDetect(m_csid,win_csid,(unsigned char *)characterCode,1);
  1332.             if(t_unicodestring)
  1333.             {
  1334.                 EDT_InsertText( pMWContext, (char *)t_unicodestring ); 
  1335.                 XP_FREE(t_unicodestring);
  1336.             }
  1337.         }
  1338.     }
  1339.     else
  1340.     {
  1341. #endif //XP_WIN32
  1342.         if( EDT_COP_OK != (iResult = CASTINT(EDT_KeyDown( GET_MWCONTEXT, nChar, nRepCnt, nflags ))) ){
  1343.           ReportCopyError(iResult);
  1344.         }
  1345. #ifdef XP_WIN32
  1346.     }
  1347. #endif
  1348. }
  1349.  
  1350. BOOL CNetscapeEditView::OnLeftKey(BOOL bShift, BOOL bControl)
  1351. {
  1352.     if (bShift && bControl)
  1353.         OnSelectPreviousWord();
  1354.     else if (bShift)
  1355.         OnSelectPreviousChar();
  1356.     else if (bControl)
  1357.         OnPreviousWord();
  1358.     else
  1359.         OnPreviousChar();
  1360.  
  1361.     return TRUE;
  1362. }
  1363.  
  1364. BOOL CNetscapeEditView::OnRightKey(BOOL bShift, BOOL bControl)
  1365. {
  1366.     if (bShift && bControl)
  1367.         OnSelectNextWord();
  1368.     else if (bShift)
  1369.         OnSelectNextChar();
  1370.     else if (bControl)
  1371.         OnNextWord();
  1372.     else
  1373.         OnNextChar();
  1374.  
  1375.     return TRUE;
  1376. }
  1377.  
  1378. BOOL CNetscapeEditView::OnDownKey(BOOL bShift, BOOL bControl)
  1379. {
  1380.     if (bShift && bControl)
  1381.         return FALSE;                     
  1382.     else if (bShift)
  1383.         OnSelectDown();
  1384.     else if (bControl)
  1385.         OnNextParagraph();                     
  1386.     else
  1387.         OnDown();
  1388.  
  1389.     return TRUE;
  1390. }
  1391.  
  1392. BOOL CNetscapeEditView::OnUpKey(BOOL bShift, BOOL bControl)
  1393. {
  1394.     if (bShift && bControl)
  1395.         return FALSE;
  1396.     else if (bShift)
  1397.         OnSelectUp();
  1398.     else if (bControl)
  1399.         OnPreviousParagraph();                     
  1400.     else
  1401.         OnUp();
  1402.  
  1403.     return TRUE;
  1404. }
  1405.  
  1406. BOOL CNetscapeEditView::OnHomeKey(BOOL bShift, BOOL bControl)
  1407. {
  1408.     if (bShift && bControl)
  1409.         OnSelectBeginOfDocument();
  1410.     else if (bShift)
  1411.         OnSelectBeginOfLine();
  1412.     else if (bControl)
  1413.         EDT_BeginOfDocument(GET_MWCONTEXT, FALSE);
  1414.     else
  1415.         OnBeginOfLine();
  1416.  
  1417.     return TRUE;
  1418. }
  1419.  
  1420. BOOL CNetscapeEditView::OnEndKey(BOOL bShift, BOOL bControl)
  1421. {
  1422.     if (bShift && bControl)
  1423.         OnSelectEndOfDocument();
  1424.     else if (bShift)
  1425.         OnSelectEndOfLine();
  1426.     else if (bControl)
  1427.         EDT_EndOfDocument(GET_MWCONTEXT, FALSE);
  1428.     else
  1429.         OnEndOfLine();
  1430.  
  1431.     return TRUE;
  1432. }
  1433.  
  1434. BOOL CNetscapeEditView::OnInsertKey(BOOL bShift, BOOL bControl)
  1435. {
  1436.     if (bShift && bControl)
  1437.         return FALSE;
  1438.     else if (bShift)
  1439.         OnEditPaste();
  1440.     else if (bControl)
  1441.         OnEditCopy();                  
  1442.     else
  1443.         return FALSE;
  1444.  
  1445.     return TRUE;
  1446. }
  1447.  
  1448. //////////////////////////////////////////////////////////////////////////////////////////
  1449. //
  1450. // Local function to terminate a string at first new-line character
  1451. // Bookmark strings (clipboard and drop formats) all need this
  1452. void wfe_TerminateStringAtNewline( char * pString )
  1453. {
  1454.     char * pCR = strstr( pString, "\n" );
  1455.     if ( pCR ) {
  1456.         *pCR = '\0';
  1457.     }
  1458. }
  1459.  
  1460. // Convert screen (e.g., mouse) point to doc coordinates
  1461. void CNetscapeEditView::ClientToDocXY( CPoint& cPoint, int32* pX, int32* pY )
  1462. {
  1463.     CWinCX *  pContext = GetContext();
  1464.     if ( !pContext)
  1465.         return;
  1466.     XY Point;
  1467.     pContext->ResolvePoint(Point, cPoint);
  1468.  
  1469.     *pX = Point.x;
  1470.     *pY = Point.y;
  1471. }
  1472.  
  1473. void ImageHack( MWContext *pContext ){
  1474.     if( EDT_GetCurrentElementType(pContext) == ED_ELEMENT_IMAGE ) {
  1475.         EDT_ImageData *pId = EDT_GetImageData(pContext);
  1476.         if( pId ){
  1477.             
  1478.             #if 0
  1479.             if( pId->pWidth ){
  1480.                 XP_FREE( pId->pWidth );
  1481.                 pId->pWidth = 0;
  1482.             }
  1483.             else {
  1484.                 pId->pWidth = XP_STRDUP( "50%" );
  1485.             }
  1486.             #endif
  1487.  
  1488.             pId->align = (ED_Alignment)(pId->align+1);
  1489.             if( (int)pId->align == 9 ){
  1490.                 pId->align = (ED_Alignment)0;
  1491.             }
  1492.  
  1493.             int bKeepImages;
  1494.             PREF_GetBoolPref("editor.publish_keep_images",&bKeepImages);
  1495.             EDT_SetImageData( pContext, pId, bKeepImages );
  1496.             EDT_FreeImageData( pId );
  1497.         }
  1498.     }
  1499. }
  1500.  
  1501. void PageHack( MWContext *pContext ){
  1502.     EDT_PageData *pPageData = EDT_GetPageData( pContext );
  1503.     if( pPageData->pColorBackground ) XP_FREE( pPageData->pColorBackground );
  1504.     pPageData->pColorBackground = XP_NEW( LO_Color );
  1505.  
  1506.     pPageData->pColorBackground->red = 0xff;
  1507.     pPageData->pColorBackground->green = 0xff;
  1508.     pPageData->pColorBackground->blue = 0x80;
  1509.  
  1510.     char *p = pPageData->pTitle;
  1511.     while( p && *p ){
  1512.         *p = toupper( *p );
  1513.         p++;
  1514.     }
  1515.  
  1516.     if( pPageData->pBackgroundImage != 0 ){
  1517.         pPageData->pBackgroundImage = 0;
  1518.     }
  1519.     else {
  1520.         pPageData->pBackgroundImage = XP_STRDUP("grunt.gif");
  1521.     }
  1522.  
  1523.     EDT_SetPageData( pContext, pPageData );
  1524.     EDT_FreePageData( pPageData );
  1525. }
  1526.  
  1527.      
  1528. void HRuleHack( MWContext *pContext ){
  1529.     if( EDT_GetCurrentElementType(pContext) == ED_ELEMENT_HRULE ) {
  1530.         EDT_HorizRuleData *pId = EDT_GetHorizRuleData(pContext);
  1531.         if( pId ){
  1532.             
  1533.             #if 0
  1534.             if( pId->pWidth ){
  1535.                 XP_FREE( pId->pWidth );
  1536.                 pId->pWidth = 0;
  1537.             }
  1538.             else {
  1539.                 pId->pWidth = XP_STRDUP( "50%" );
  1540.             }
  1541.             #endif
  1542.  
  1543.             pId->size = (pId->size + 10 % 100 );
  1544.             pId->bNoShade = TRUE;
  1545.  
  1546.             EDT_SetHorizRuleData( pContext, pId );
  1547.             EDT_FreeHorizRuleData( pId );
  1548.         }
  1549.     }
  1550. }
  1551.  
  1552. void CNetscapeEditView::OnNextParagraph()
  1553. {
  1554.     if ( GetContext() && GET_MWCONTEXT) {
  1555.         //EDT_Down(GET_MWCONTEXT);  TODO: IMPLEMENT OnNextParagraph and OnPreviousParagraph
  1556.     }
  1557. }
  1558.  
  1559. void CNetscapeEditView::OnPreviousParagraph()
  1560. {
  1561.     if ( GetContext() && GET_MWCONTEXT) {
  1562.         //EDT_Up(GET_MWCONTEXT);
  1563.     }
  1564. }
  1565.  
  1566. void CNetscapeEditView::OnUp()
  1567. {
  1568.     if ( GetContext() && GET_MWCONTEXT ) {
  1569.         EDT_Up( GET_MWCONTEXT, FALSE );
  1570.     }
  1571. }
  1572.  
  1573. void CNetscapeEditView::OnDown()
  1574. {
  1575.     if ( GetContext() && GET_MWCONTEXT ) {
  1576.         EDT_Down( GET_MWCONTEXT, FALSE );
  1577.     }
  1578. }
  1579.  
  1580. void CNetscapeEditView::OnNextChar()
  1581. {
  1582.     if ( GetContext() && GET_MWCONTEXT ) {
  1583.         EDT_NextChar( GET_MWCONTEXT, FALSE );
  1584.     }
  1585. }
  1586.  
  1587. void CNetscapeEditView::OnPreviousChar()
  1588. {
  1589.     if ( GetContext() && GET_MWCONTEXT ) {
  1590.         EDT_PreviousChar( GET_MWCONTEXT, FALSE );
  1591.     }
  1592. }
  1593.  
  1594. void CNetscapeEditView::OnBeginOfLine()
  1595. {
  1596.     if ( GetContext() && GET_MWCONTEXT ) {
  1597.         EDT_BeginOfLine( GET_MWCONTEXT, FALSE );
  1598.     }
  1599. }
  1600.  
  1601. void CNetscapeEditView::OnEndOfLine()
  1602. {
  1603.     if ( GetContext() && GET_MWCONTEXT ) {
  1604.         EDT_EndOfLine( GET_MWCONTEXT, FALSE );
  1605.     }
  1606. }
  1607.  
  1608. void CNetscapeEditView::OnPageUp()
  1609. {
  1610.     if ( GetContext() && GET_MWCONTEXT ) {
  1611.         EDT_PageUp( GET_MWCONTEXT, FALSE );
  1612.     }
  1613. }
  1614.  
  1615. void CNetscapeEditView::OnPageDown()
  1616. {
  1617.     if ( GetContext() && GET_MWCONTEXT ) {
  1618.         EDT_PageDown( GET_MWCONTEXT, FALSE );
  1619.     }
  1620. }
  1621.  
  1622. void CNetscapeEditView::OnNextWord()
  1623. {
  1624.     if ( GetContext() && GET_MWCONTEXT) {
  1625.         EDT_NextWord(GET_MWCONTEXT, FALSE);
  1626.     }
  1627. }
  1628.  
  1629. void CNetscapeEditView::OnPreviousWord()
  1630. {
  1631.     if ( GetContext() && GET_MWCONTEXT) {
  1632.        EDT_PreviousWord(GET_MWCONTEXT, FALSE);
  1633.     }
  1634. }
  1635.  
  1636. void CNetscapeEditView::OnSelectUp()
  1637. {
  1638.     if ( GetContext() && GET_MWCONTEXT ) {
  1639.         EDT_Up( GET_MWCONTEXT, TRUE );
  1640.     }
  1641. }
  1642.  
  1643. void CNetscapeEditView::OnSelectDown()
  1644. {
  1645.     if ( GetContext() && GET_MWCONTEXT ) {
  1646.         EDT_Down( GET_MWCONTEXT, TRUE );
  1647.     }
  1648. }
  1649.  
  1650. void CNetscapeEditView::OnSelectNextChar()
  1651. {
  1652.     if ( GetContext() && GET_MWCONTEXT ) {
  1653.         EDT_NextChar( GET_MWCONTEXT, TRUE );
  1654.     }
  1655. }
  1656.  
  1657. void CNetscapeEditView::OnSelectPreviousChar()
  1658. {
  1659.     if ( GetContext() && GET_MWCONTEXT ) {
  1660.         EDT_PreviousChar( GET_MWCONTEXT, TRUE );
  1661.     }
  1662. }
  1663.  
  1664. void CNetscapeEditView::OnSelectBeginOfLine()
  1665. {
  1666.     if ( GetContext() && GET_MWCONTEXT ) {
  1667.         EDT_BeginOfLine( GET_MWCONTEXT, TRUE );
  1668.     }
  1669. }
  1670.  
  1671. void CNetscapeEditView::OnSelectEndOfLine()
  1672. {
  1673.     if ( GetContext() && GET_MWCONTEXT ) {
  1674.         EDT_EndOfLine( GET_MWCONTEXT, TRUE );
  1675.     }
  1676. }
  1677.  
  1678. void CNetscapeEditView::OnSelectPageUp()
  1679. {
  1680.     if ( GetContext() && GET_MWCONTEXT ) {
  1681.         EDT_PageUp( GET_MWCONTEXT, TRUE );
  1682.     }
  1683. }
  1684.  
  1685. void CNetscapeEditView::OnSelectPageDown()
  1686. {
  1687.     if ( GetContext() && GET_MWCONTEXT ) {
  1688.         EDT_PageDown( GET_MWCONTEXT, TRUE );
  1689.     }
  1690. }
  1691.  
  1692. void CNetscapeEditView::OnSelectBeginOfDocument()
  1693. {
  1694.     if ( GetContext() && GET_MWCONTEXT ) {
  1695.         EDT_BeginOfDocument( GET_MWCONTEXT, TRUE );
  1696.     }
  1697. }
  1698.  
  1699. void CNetscapeEditView::OnSelectEndOfDocument()
  1700. {
  1701.     if ( GetContext() && GET_MWCONTEXT ) {
  1702.         EDT_EndOfDocument( GET_MWCONTEXT, TRUE );
  1703.     }
  1704. }
  1705.  
  1706. void CNetscapeEditView::OnSelectNextWord()
  1707. {
  1708.     if ( GetContext() && GET_MWCONTEXT) {
  1709.         EDT_NextWord(GET_MWCONTEXT, TRUE );
  1710.     }
  1711. }
  1712.  
  1713. void CNetscapeEditView::OnSelectPreviousWord()
  1714. {
  1715.     if ( GetContext() && GET_MWCONTEXT) {
  1716.         EDT_PreviousWord(GET_MWCONTEXT, TRUE);
  1717.     }
  1718. }
  1719.  
  1720. //
  1721. // Global FE functions so it is accessible from anyone who needs it
  1722.  
  1723. BOOL FE_ResolveLinkURL( MWContext* pMWContext, CString& csURL, BOOL bAutoAdjustLinks )
  1724. {
  1725.     csURL.TrimLeft();
  1726.     csURL.TrimRight();
  1727.  
  1728.     // Empty is OK - this is how we remove links
  1729.     if ( csURL.IsEmpty() ){
  1730.         return TRUE;
  1731.     }
  1732.     // Don't try to make relative to file://Untitled.
  1733.     if (EDT_IS_NEW_DOCUMENT(pMWContext)){
  1734.       return TRUE;
  1735.     }
  1736.           
  1737.     // Base URL is the address of current document
  1738.     History_entry * hist_ent = SHIST_GetCurrent(&(pMWContext->hist));
  1739.     if ( hist_ent == NULL || hist_ent->address == NULL ){
  1740.         return FALSE;
  1741.     }
  1742.     // Be sure we are URL format first
  1743.     CString csTemp;
  1744.     WFE_ConvertFile2Url(csTemp, csURL);
  1745.     char *szRelativeURL = NULL;
  1746.     int Result = NET_MakeRelativeURL( hist_ent->address,
  1747.                                       (char*)(LPCSTR(csTemp)), // Input URL
  1748.                                       &szRelativeURL);           // Result put here
  1749.     switch( Result ){
  1750.         case NET_URL_SAME_DIRECTORY:
  1751.             TRACE0("NET_URL_SAME_DIRECTORY\n");
  1752.             break;
  1753.         case NET_URL_SAME_DEVICE:
  1754.             TRACE0("NET_URL_SAME_DEVICE\n");
  1755.             break;
  1756.         case NET_URL_NOT_ON_SAME_DEVICE:
  1757.             // Warn user if they try to make a link to a different local device
  1758.             // (HTTP: URLs are OK)
  1759.             if ( bAutoAdjustLinks && NET_IsLocalFileURL(szRelativeURL) ){
  1760.                 // Start message with a size-limited version of URL
  1761.                 CString csMsg = szRelativeURL;
  1762.                 WFE_CondenseURL(csMsg, 50, FALSE);
  1763.                 // add rest of message from resources
  1764.                 csMsg += szLoadString(IDS_ERR_DIF_LOCAL_DEVICE_LINK);
  1765.  
  1766.                 if ( IDNO == ::MessageBox( PANECX(pMWContext)->GetPane(),
  1767.                                          LPCSTR(csMsg),
  1768.                                          szLoadString(IDS_RESOLVE_LINK_URL),
  1769.                                          MB_YESNO | MB_ICONQUESTION ) ){
  1770.                     // Cancel using string
  1771.                     XP_FREE( szRelativeURL );
  1772.                     szRelativeURL = NULL;
  1773.                 }
  1774.             }
  1775.             break;
  1776.         case NET_URL_FAIL:                  // Failed for lack of params, etc.
  1777.             TRACE0("NET_URL_FAIL\n");
  1778.             break;
  1779.     }
  1780.  
  1781.     if ( szRelativeURL ){
  1782.         csURL = szRelativeURL;
  1783.         XP_FREE( szRelativeURL );
  1784.         return TRUE;
  1785.     }
  1786.     return FALSE;
  1787. }
  1788.  
  1789. void CNetscapeEditView::OnGoToDefaultPublishLocation()
  1790. {
  1791.     // Get editor app from preferences or prompt user to edit preferences        
  1792.     CString csBrowseLocation = 
  1793.         ((CEditFrame*)GetFrame())->GetLocationFromPreferences("editor.publish_browse_location",
  1794.                                           IDS_BROWSETO_PROMPT,
  1795.                                           IDS_BROWSETO_CAPTION,
  1796.                                           IDS_SELECT_BROWSETO_CAPTION);
  1797.     if(!csBrowseLocation.IsEmpty()){
  1798.         GetContext()->NormalGetUrl((char*)LPCSTR(csBrowseLocation));
  1799.     }
  1800. }
  1801.  
  1802. void CNetscapeEditView::OnEditCopy()
  1803. {
  1804.     CWnd * pWnd = GetFocus();
  1805.     if( pWnd != this ){
  1806.         // If not in editor view, probably in Address
  1807.         //   area, so send message there
  1808.         if( pWnd )
  1809.             pWnd->PostMessage(WM_COPY,0,0);
  1810.         return;
  1811.     }
  1812.     HANDLE h;
  1813.     HANDLE hData;
  1814.     XP_HUGE_CHAR_PTR string;
  1815.     char * text;
  1816.     int iResult;
  1817.     CWinCX * pContext = GetContext();
  1818.     if(!pContext)
  1819.       return;
  1820.  
  1821.     MWContext* pMWContext = pContext->GetContext();
  1822.     
  1823.     // TODO: CHECK FOR INDIVIDUALLY-SELECTED IMAGE AND COPY USING EDT_CopyImageData struct
  1824.  
  1825.     int32 textLen, hLen;
  1826.     XP_HUGE_CHAR_PTR htmlData = 0;
  1827.     SetCursor(theApp.LoadStandardCursor(IDC_WAIT));
  1828.     if( EDT_COP_OK != (iResult = CASTINT(EDT_CopySelection(pMWContext, &text, &textLen, &htmlData, &hLen))) ){
  1829.         ReportCopyError(iResult);
  1830.         return;
  1831.     }
  1832.     SetCursor(theApp.LoadStandardCursor(IDC_ARROW));
  1833.     if(!text)
  1834.       return;
  1835.  
  1836.     if(!CWnd::OpenClipboard()) {
  1837.         FE_Alert(pMWContext, szLoadString(IDS_OPEN_CLIPBOARD));
  1838.         return;
  1839.     }
  1840.  
  1841.     if(!EmptyClipboard()) {
  1842.         FE_Alert(pMWContext, szLoadString(IDS_EMPTY_CLIPBOARD));
  1843.         return;
  1844.     }
  1845.                   
  1846.     int32 len = XP_STRLEN(text) + 1;
  1847.     
  1848.     hData = GlobalAlloc(GMEM_MOVEABLE, (DWORD) len);
  1849.     string = (char *) GlobalLock(hData);
  1850.     XP_MEMCPY( string, text, CASTSIZE_T(len) );
  1851.     string[len - 1] = '\0';
  1852.     GlobalUnlock(hData);
  1853.  
  1854.     h = SetClipboardData(CF_TEXT, hData); 
  1855.  
  1856. #ifdef XP_WIN32
  1857.     int datacsid = INTL_GetCSIWinCSID(
  1858.                         LO_GetDocumentCharacterSetInfo(pMWContext))
  1859.                             & ~CS_AUTO;
  1860.  
  1861.     if((CS_USER_DEFINED_ENCODING != datacsid) && (0 != datacsid))
  1862.     {
  1863.         len = CASTINT((INTL_StrToUnicodeLen(datacsid, (unsigned char*)text)+1) * 2);
  1864.         hData = GlobalAlloc(GMEM_MOVEABLE, (DWORD) len);
  1865.         string = (char *) GlobalLock(hData);
  1866.         INTL_StrToUnicode(datacsid, (unsigned char*)text, (INTL_Unicode*)string, len);
  1867.  
  1868.         GlobalUnlock(hData);        
  1869.     }
  1870.     h = ::SetClipboardData(CF_UNICODETEXT, hData); 
  1871.  
  1872. #endif
  1873.  
  1874.     if( htmlData ){
  1875.         hData = GlobalAlloc(GMEM_MOVEABLE, (DWORD) hLen);
  1876.         string = (char *) GlobalLock(hData);
  1877.         XP_HUGE_MEMCPY(string, htmlData, hLen);
  1878.         GlobalUnlock(hData);
  1879.         h = SetClipboardData(m_cfEditorFormat, hData); 
  1880.     }
  1881.     XP_HUGE_FREE( htmlData );
  1882.  
  1883.  
  1884.     CloseClipboard();
  1885.     XP_FREE(text);
  1886.     BOOL bCanPaste = (BOOL)EDT_CanPaste(pContext->GetContext(), TRUE);
  1887.     TRACE1("Can paste=%d\n", bCanPaste);
  1888. }     
  1889.  
  1890. void CNetscapeEditView::ReportCopyError(int iError)
  1891. {
  1892.     SetCursor(theApp.LoadStandardCursor(IDC_ARROW));
  1893.     UINT nIDS = 0;
  1894.     switch(iError) {
  1895.         case EDT_COP_DOCUMENT_BUSY:
  1896.             nIDS = IDS_DOCUMENT_BUSY;
  1897.             break;
  1898.         //TODO: Maybe don't do this message either?
  1899.         // This doesn't occur as often with new table selection model
  1900.         case EDT_COP_SELECTION_CROSSES_TABLE_DATA_CELL:
  1901.             nIDS = IDS_SELECTION_CROSSES_TABLE_DATA_CELL;
  1902.             break;
  1903.     }
  1904.     // Trap case where error tells us its a table error,
  1905.     //  but really there's nothing selected, thus nothing to delete
  1906.     if( nIDS == IDS_SELECTION_CROSSES_TABLE_DATA_CELL && 
  1907.         !EDT_IsSelected(GET_MWCONTEXT) ) {
  1908.         nIDS = 0; //IDS_NOTHING_TO_DELETE; Don't do message if just no selection
  1909.     }
  1910.  
  1911.     if( nIDS ){
  1912.         MessageBox( szLoadString(nIDS),
  1913.                     szLoadString(IDS_COPY_ERROR_CAPTION), 
  1914.                     MB_OK | MB_ICONINFORMATION );
  1915.     }
  1916. }
  1917.  
  1918. void CNetscapeEditView::OnEditCut()
  1919. {
  1920.     CWnd * pWnd = GetFocus();
  1921.     if( pWnd != this ){
  1922.         // If not in editor view, probably in Address
  1923.         //   area, so send message there
  1924.         if( pWnd )
  1925.             pWnd->PostMessage(WM_CUT,0,0);
  1926.         return;
  1927.     }
  1928.     HANDLE h;
  1929.     HANDLE hData;
  1930.     char * string;
  1931.     char * text;
  1932.     CWinCX *     pContext = GetContext();
  1933.     if ( !pContext ) {
  1934.         return;
  1935.     }
  1936.     MWContext  * pMWContext = pContext->GetContext();
  1937.     int iResult;
  1938.     
  1939.     // Don't bother if no selection
  1940.     if(!pMWContext  ||
  1941.        !m_bIsEditor )
  1942.     {
  1943.         return;
  1944.     }
  1945.  
  1946.     int32 textLen, hLen;
  1947.     XP_HUGE_CHAR_PTR htmlData = 0;
  1948.     SetCursor(theApp.LoadStandardCursor(IDC_WAIT));
  1949.     if( EDT_COP_OK != (iResult = CASTINT(EDT_CutSelection(pMWContext, &text, &textLen, &htmlData, &hLen)) )||
  1950.         !text ) {
  1951.         ReportCopyError(iResult);
  1952.         return;
  1953.     }
  1954.     SetCursor(theApp.LoadStandardCursor(IDC_ARROW));
  1955.  
  1956.  
  1957.     if(!CWnd::OpenClipboard()) {
  1958.        FE_Alert(pMWContext, szLoadString(IDS_OPEN_CLIPBOARD));
  1959.         return;
  1960.     }
  1961.  
  1962.     if(!EmptyClipboard()) {
  1963.         FE_Alert(pMWContext, szLoadString(IDS_EMPTY_CLIPBOARD));
  1964.         return;
  1965.     }
  1966.                   
  1967.     int len = XP_STRLEN(text) + 1;
  1968.     
  1969.     hData = GlobalAlloc(GMEM_MOVEABLE, (DWORD) len);
  1970.     string = (char *) GlobalLock(hData);
  1971.     strncpy(string, text, len);
  1972.     string[len - 1] = '\0';
  1973.     GlobalUnlock(hData);
  1974.  
  1975.     h = SetClipboardData(CF_TEXT, hData); 
  1976.  
  1977. #ifdef XP_WIN32
  1978.     int datacsid = INTL_GetCSIWinCSID(
  1979.                         LO_GetDocumentCharacterSetInfo(GetContext()->GetContext()))
  1980.                             & ~CS_AUTO;
  1981.  
  1982.     if((CS_USER_DEFINED_ENCODING != datacsid) && (0 != datacsid))
  1983.     {
  1984.         len = CASTINT((INTL_StrToUnicodeLen(datacsid, (unsigned char*)text)+1) * 2);
  1985.         hData = GlobalAlloc(GMEM_MOVEABLE, (DWORD) len);
  1986.         string = (char *) GlobalLock(hData);
  1987.         INTL_StrToUnicode(datacsid, (unsigned char*)text, (INTL_Unicode*)string, len);
  1988.  
  1989.         GlobalUnlock(hData);        
  1990.     }
  1991.     h = ::SetClipboardData(CF_UNICODETEXT, hData); 
  1992.  
  1993. #endif
  1994.  
  1995.     if( htmlData ){
  1996.         hData = GlobalAlloc(GMEM_MOVEABLE, (DWORD) hLen);
  1997.         string = (char *) GlobalLock(hData);
  1998.         XP_HUGE_MEMCPY(string, htmlData, hLen);
  1999.         GlobalUnlock(hData);
  2000.         h = SetClipboardData(m_cfEditorFormat, hData); 
  2001.     }
  2002.     XP_HUGE_FREE( htmlData );
  2003.  
  2004.     CloseClipboard();
  2005.     XP_FREE(text);
  2006. }     
  2007.  
  2008. void CNetscapeEditView::OnEditDelete()
  2009. {
  2010.     if ( GET_MWCONTEXT != NULL ) {
  2011.         int iResult;
  2012.         SetCursor(theApp.LoadStandardCursor(IDC_WAIT));
  2013.         if( EDT_COP_OK == (iResult = CASTINT(EDT_DeleteChar(GET_MWCONTEXT))) ){
  2014.         } else {
  2015.             ReportCopyError(iResult);
  2016.         }
  2017.     }
  2018. }
  2019.  
  2020. void CNetscapeEditView::OnCopyStyle()
  2021. {
  2022.     EDT_CopyStyle(GET_MWCONTEXT);
  2023. }
  2024.  
  2025. void CNetscapeEditView::OnUpdateCopyStyle(CCmdUI* pCmdUI)
  2026. {
  2027.     //TODO: CHECK FOR TEXT ELEMENT?
  2028.     pCmdUI->Enable(CAN_INTERACT);
  2029. }
  2030.  
  2031. // Use this for any commands that are enabled most of the time
  2032. void CNetscapeEditView::OnCanInteract(CCmdUI* pCmdUI)
  2033. {
  2034.     pCmdUI->Enable(CAN_INTERACT);
  2035. }
  2036.  
  2037. // Gets data from bookmark item - returns TRUE if found
  2038. BOOL wfe_GetBookmarkData( COleDataObject* pDataObject, char ** ppURL, char ** ppTitle ) {
  2039.     HGLOBAL h = pDataObject->GetGlobalData(RegisterClipboardFormat(NETSCAPE_BOOKMARK_FORMAT));
  2040.     
  2041.     if ( h == NULL || ppTitle == NULL || ppURL == NULL ){
  2042.         return FALSE;
  2043.     }
  2044.  
  2045.     LPBOOKMARKITEM pBookmark = (LPBOOKMARKITEM)GlobalLock(h);
  2046.     if (!pBookmark){
  2047.         GlobalUnlock(h);
  2048.         return FALSE;
  2049.     }
  2050.     *ppTitle = XP_STRDUP(pBookmark->szText);
  2051.     *ppURL = XP_STRDUP(pBookmark->szAnchor);
  2052.     GlobalUnlock(h);
  2053.     return TRUE;
  2054. }
  2055.  
  2056. // Common Paste handler for Clipboard or drag/drop
  2057. BOOL CNetscapeEditView::DoPasteItem(COleDataObject* pDataObject, 
  2058.                                 CPoint *pPoint, BOOL bDeleteSource )
  2059. {
  2060.     CWinCX *     pContext = GetContext();
  2061.     if ( !pContext ) {
  2062.         return(FALSE);    
  2063.     }
  2064.     MWContext  * pMWContext = pContext->GetContext();
  2065.     // Assume drop data is from dragged object
  2066.     BOOL bDropObject = TRUE;
  2067.     
  2068.     if(!pMWContext ) {
  2069.         return(FALSE);
  2070.     }
  2071.  
  2072.     // use clipboard data if not doing drag/drop
  2073.     COleDataObject clipboardData;
  2074.     if (pDataObject == NULL)
  2075.     {
  2076.         if ( ! clipboardData.AttachClipboard() ){
  2077.             return FALSE;
  2078.         }        
  2079.         pDataObject = &clipboardData;
  2080.         // No data on clipboard?
  2081.         if (
  2082. #ifdef XP_WIN32
  2083.                  !pDataObject->m_bClipboard ||
  2084. #endif
  2085.                  -1 == GetPriorityClipboardFormat(m_pClipboardFormats, MAX_CLIPBOARD_FORMATS )) {
  2086.             return FALSE;
  2087.         }
  2088.         bDropObject = FALSE;
  2089.     }
  2090.  
  2091.     CPoint cDocPoint;
  2092.     int32  xVal, yVal;
  2093.     BOOL bPtInSelection = FALSE;
  2094.  
  2095.     if ( pPoint == NULL )
  2096.     {
  2097.         // Use last caret location if no point supplied
  2098.         cDocPoint.x = m_caret.x;
  2099.         cDocPoint.y = m_caret.y;
  2100.         pPoint = &cDocPoint;
  2101.     } else {
  2102.         cDocPoint = *pPoint;
  2103.     }
  2104.  
  2105.     // Convert everything to Document coordinates
  2106.     ClientToDocXY( cDocPoint, &xVal, &yVal );
  2107.     cDocPoint.x = CASTINT(xVal);
  2108.     cDocPoint.y = CASTINT(yVal);
  2109.     
  2110.     // We are doing Drag/Drop if we have an object
  2111.     if( bDropObject ){
  2112.         bPtInSelection = GetContext()->PtInSelectedRegion(cDocPoint);
  2113.     }
  2114.  
  2115.     // Don't do anything if drag source is selected region and
  2116.     //   drop target is same.
  2117.     if ( GetContext()->IsDragging() && bPtInSelection ) {
  2118.         return(FALSE);
  2119.     }
  2120.  
  2121.     HGLOBAL hString = NULL;
  2122.     char * pString = NULL;
  2123.  
  2124.     // Get any string data
  2125.     if ( pDataObject->IsDataAvailable(CF_TEXT) ) {
  2126.         hString = pDataObject->GetGlobalData(CF_TEXT);
  2127.  
  2128.         // get a pointer to the actual bytes
  2129.         if ( hString ) {
  2130.             pString = (char *) GlobalLock(hString);    
  2131.         }
  2132.     }
  2133.  
  2134.     if ( m_bIsEditor )
  2135.     {
  2136.         CWinCX    * pContext = GetContext();
  2137.         MWContext * pMWContext = pContext->GetContext();
  2138.         HGLOBAL     h;
  2139.         char        *pURL;
  2140.         char        *pTitle;
  2141.         SetCursor(theApp.LoadStandardCursor(IDC_WAIT));
  2142.  
  2143.         EDT_BeginBatchChanges(pMWContext);
  2144.  
  2145.         if( bDeleteSource ){
  2146.             // This deletes current selection and sets
  2147.             //  cursor at point where moved data will be inserted.
  2148.             EDT_DeleteSelectionAndPositionCaret( pMWContext, xVal, yVal );
  2149.         } else if( !bPtInSelection && bDropObject ) {
  2150.             // Remove existing selection and set new caret position
  2151.             //   to the drop ONLY if doing a drop NOT within the selection
  2152.             EDT_PositionCaret( pMWContext, xVal, yVal );
  2153.         }
  2154.  
  2155.         // Drop according to type of data
  2156.         if( pDataObject->IsDataAvailable(m_cfBookmarkFormat) &&
  2157.             wfe_GetBookmarkData(pDataObject, &pURL, &pTitle) ){
  2158.             // Create new link: insert both Anchor text and HREF,
  2159.             // First resolve (convert to relative) URL
  2160.             CString csURL = pURL;
  2161.             char *pTitleText = pTitle;
  2162.             int bKeepLinks;
  2163.             PREF_GetBoolPref("editor.publish_keep_links",&bKeepLinks);
  2164.  
  2165.             if ( FE_ResolveLinkURL(pMWContext, csURL,bKeepLinks) ){
  2166.                 // Check for ugly format from Livewire Sitemanager:
  2167.                 if( 0 == _strnicmp(pTitle, "File: file://", 13) ){
  2168.                     // Skip over redundant "File: "
  2169.                     pTitleText += 6;
  2170.                 }
  2171.                 // Bug in Sitemanager: treats graphic files that are not
  2172.                 //  "managed" as a link. Convert to image 
  2173.                 char * pExt = strrchr( pURL, '.');
  2174.                 if( CanSupportImageFile(pExt) ){
  2175.                     EDT_ImageData* pEdtData = EDT_NewImageData();
  2176.                     if( pEdtData ){
  2177.                         // We just need to set the URL
  2178.                         pEdtData->pSrc = pURL;
  2179.  
  2180.                         int bKeepImages;
  2181.                         PREF_GetBoolPref("editor.publish_keep_images",&bKeepImages);
  2182.  
  2183.                         EDT_InsertImage(pMWContext, pEdtData,bKeepImages);
  2184.                         EDT_FreeImageData(pEdtData);
  2185.                         // String was just freed, so prevent double free
  2186.                         pURL = NULL;
  2187.                     }
  2188.                 } else {
  2189.                     char * pRelative = (char*)LPCSTR(csURL);
  2190.                     if( bPtInSelection ){
  2191.                         // Make selected text/image a link to dropped item
  2192.                         EDT_SetHREF( pMWContext, pRelative );
  2193.                     } else {
  2194.                         // Insert a new link, including link (Title) text
  2195.                         EDT_PasteHREF( pMWContext, &pRelative, &pTitleText, 1 );
  2196.                     }
  2197.                 }
  2198.             }
  2199.             if( pURL) XP_FREE(pURL);
  2200.             XP_FREE(pTitle);
  2201.         } else if ( pDataObject->IsDataAvailable(m_cfEditorFormat) ) {
  2202.             h = pDataObject->GetGlobalData(m_cfEditorFormat);
  2203.             if( h ){
  2204.                 char * pHTML = (char*) GlobalLock( h );
  2205.                 EDT_PasteHTML( pMWContext, pHTML );
  2206.                 GlobalUnlock( h );
  2207.             }
  2208.         } 
  2209. #ifdef EDITOR
  2210.         else if(pDataObject->IsDataAvailable(m_cfImageFormat) ) {
  2211.             h = pDataObject->GetGlobalData(m_cfImageFormat);
  2212.             WFE_DragDropImage(h, pMWContext);
  2213.         } 
  2214. #endif // EDITOR
  2215. #ifdef XP_WIN32
  2216.         else if( pDataObject->IsDataAvailable(CF_HDROP) ){
  2217.             HDROP handle = (HDROP)pDataObject->GetGlobalData(CF_HDROP);
  2218.             if( handle ){
  2219.                 // Do same thing we would do for Win3.x and NT
  2220.                 //  (old-style file-manager-drop)
  2221.                 // FALSE = caret is already positioned correctly
  2222.                 DropFiles(handle, FALSE);
  2223.             }
  2224.         // **** Test for other formats here
  2225.         } 
  2226.         else if ( pDataObject->IsDataAvailable(CF_UNICODETEXT) && 
  2227.                     (CS_USER_DEFINED_ENCODING != INTL_GetCSIWinCSID(LO_GetDocumentCharacterSetInfo(pMWContext)))
  2228.                   )    {    // Let's try CF_UNICODETEXT before CF_TEXT
  2229.             
  2230.             int datacsid = 
  2231.                 INTL_GetCSIWinCSID(LO_GetDocumentCharacterSetInfo(pMWContext)) & ~CS_AUTO;
  2232.             HGLOBAL hUnicodeStr = NULL;
  2233.             char * pUnicodeString = NULL;
  2234.             char * pConvertedString = NULL;
  2235.  
  2236.             // Get any string data
  2237.             if ( pDataObject->IsDataAvailable(CF_UNICODETEXT) ) {
  2238.                 hUnicodeStr = pDataObject->GetGlobalData(CF_UNICODETEXT);
  2239.  
  2240.                 // get a pointer to the actual bytes
  2241.                 if ( hUnicodeStr ) {
  2242.                     pUnicodeString = (char *) GlobalLock(hUnicodeStr);    
  2243.  
  2244.                     // Now, let's convert the Unicode text into the datacsid encoding
  2245.                     int ucs2len = CASTINT(INTL_UnicodeLen((INTL_Unicode*)pUnicodeString));
  2246.                     int    mbbufneeded = CASTINT(INTL_UnicodeToStrLen(datacsid, 
  2247.                                                                     (INTL_Unicode*)pUnicodeString, 
  2248.                                                                     ucs2len));
  2249.                     if(NULL != (pConvertedString = (char*)XP_ALLOC(mbbufneeded + 1)))
  2250.                     {
  2251.                         INTL_UnicodeToStr(datacsid, (INTL_Unicode*)pUnicodeString, ucs2len, 
  2252.                                                     (unsigned char*) pConvertedString, mbbufneeded + 1);
  2253.                         
  2254.                         EDT_PasteText( pMWContext, pConvertedString ); 
  2255.                         XP_FREE(pConvertedString);
  2256.                     }
  2257.                     GlobalUnlock(hUnicodeStr);    
  2258.                 }
  2259.             }
  2260.         }
  2261. #endif //XP_WIN32
  2262.         else if ( pDataObject->IsDataAvailable(CF_TEXT) ) {
  2263.             if( pString ) {
  2264.                 // *** TODO: Analyze string:
  2265.                 // Check if its a valid local filename (use XP_STAT). If yes, pop-up menu:
  2266.                 //    1. If over selected text: Create a link to 
  2267.                 //         Pop-up menu: Create Link or paste filename or load file
  2268.                 //    2. If over an existing link:
  2269.                 //         Pop-up menu: Modify Link or load file or 
  2270.                 //    3. In ordinary text:
  2271.                 //         Popup:  Insert Link or paste filename or load file
  2272.                 
  2273.                 EDT_PasteText( pMWContext, pString ); 
  2274.             }
  2275.         }
  2276. #ifdef EDITOR
  2277. #ifdef _IMAGE_CONVERT
  2278.         else if( pDataObject->IsDataAvailable(CF_DIB) ) {
  2279.             CONVERT_IMGCONTEXT imageContext;
  2280.             CONVERT_IMG_INFO imageInfo;
  2281.             memset(&imageContext,0,sizeof(CONVERT_IMGCONTEXT));
  2282.             HBITMAP handle = (HBITMAP)pDataObject->GetGlobalData(CF_DIB);
  2283.             if (handle)
  2284.             {
  2285.                 imageContext.m_stream.m_type=CONVERT_MEMORY;
  2286.                 imageContext.m_stream.m_mem=(XP_HUGE_CHAR_PTR)GlobalLock(handle);
  2287.                 if (imageContext.m_stream.m_mem)
  2288.                 {
  2289.                     imageContext.m_imagetype=conv_bmp;
  2290.                     imageContext.m_callbacks.m_dialogimagecallback=FE_ImageConvertDialog;
  2291.                     imageContext.m_callbacks.m_displaybuffercallback=FE_ImageConvertDisplayBuffer;
  2292.                     imageContext.m_callbacks.m_completecallback=FE_ImageDoneCallBack;
  2293.                     imageContext.m_pMWContext=pMWContext;
  2294.                     imageContext.m_parentwindow=(void *)this;
  2295.                     CONVERT_IMAGERESULT result=convert_stream2image(imageContext,&imageInfo,1,NULL);//1 for 1 output
  2296.                     GlobalUnlock(handle);
  2297.                     if (result>CONV_OK)//not cancel or ok
  2298.                     {
  2299.                         AfxMessageBox(m_converrmsg[result]);
  2300.                     }
  2301.                 }
  2302.             }
  2303.         } 
  2304. #endif //_IMAGE_CONVERT
  2305. #endif // EDITOR
  2306.     } else if ( pString) {              // Navigator window - assume string is a URL
  2307.         char * szURL = XP_STRDUP(pString);
  2308.         // Maybe check for valid local filename here?
  2309.         if ( NET_URL_Type != 0 ) {
  2310.             GetContext()->NormalGetUrl(szURL);
  2311.         }
  2312.         XP_FREE(szURL);
  2313.     }
  2314.  
  2315.     if ( hString ) {
  2316.         GlobalUnlock(hString);
  2317.     }
  2318.     
  2319.     if ( m_bIsEditor )
  2320.         EDT_EndBatchChanges(pMWContext);
  2321.  
  2322.     SetCursor(theApp.LoadStandardCursor(IDC_ARROW));
  2323.  
  2324.     return(TRUE);
  2325. }
  2326.  
  2327. void CNetscapeEditView::OnEditPaste(){
  2328.  
  2329.     CWnd * pWnd = GetFocus();
  2330.     if( pWnd != this ){
  2331.         // If not in editor view, probably in Address
  2332.         //   area, so send message there
  2333.         if( pWnd )
  2334.             pWnd->PostMessage(WM_PASTE,0,0);
  2335.         return;
  2336.     }
  2337.  
  2338.     // NULL params tell it to use clipboard for data source
  2339.     //  and current caret position.
  2340.     CWinCX *pContext = GetContext();
  2341.     if ( m_bIsEditor && pContext
  2342.         && EDT_COP_OK != EDT_CanPaste(pContext->GetContext(), TRUE) )
  2343.         return;
  2344.     DoPasteItem(NULL, NULL, FALSE );
  2345. }
  2346.  
  2347. BOOL UpdateCanCopyInEditControl(CWnd *pView, CCmdUI* pCmdUI)
  2348. {
  2349.     CWnd *pWnd = pView->GetFocus();
  2350.     // We are in the view - check for selection in edit buffer instead
  2351.     if( pView == pWnd )
  2352.         return FALSE;
  2353.  
  2354.     // If control with focus is CEdit, then check if there is a selection
  2355.     if( pWnd && pWnd->IsKindOf(RUNTIME_CLASS(CEdit)) ){
  2356.         // We have a selection if start and end are different.
  2357.         DWORD dwStart, dwEnd;
  2358.         pWnd->SendMessage(EM_GETSEL, (WPARAM)(LPDWORD)&dwStart, 
  2359.                           (LPARAM)(LPDWORD)&dwEnd);
  2360.         pCmdUI->Enable(dwStart != dwEnd);
  2361.     } else {
  2362.         pCmdUI->Enable(FALSE);
  2363.     }
  2364.     return TRUE;
  2365. }
  2366.  
  2367. void CNetscapeEditView::OnUpdateEditCut(CCmdUI* pCmdUI)
  2368. {
  2369.     if( UpdateCanCopyInEditControl(this, pCmdUI) )
  2370.         return;
  2371.  
  2372.     CWinCX *pContext = GetContext();
  2373.     if ( pContext && !m_imebool){//added check for IME composition)
  2374.             // False means allow attempt when crossing table cell 
  2375.             //  but tell user why later
  2376.         pCmdUI->Enable(CAN_INTERACT && EDT_COP_OK == EDT_CanCut(pContext->GetContext(), FALSE));
  2377.     } else { 
  2378.         pCmdUI->Enable(FALSE);
  2379.     }
  2380. }
  2381.  
  2382. // Something like this should be used by the non-editor version as well,
  2383. //    but use LO_HaveSelection instead of EDT_IsSelected
  2384. void CNetscapeEditView::OnUpdateEditCopy(CCmdUI* pCmdUI)
  2385. {
  2386.     if( UpdateCanCopyInEditControl(this, pCmdUI) )
  2387.         return;
  2388.  
  2389.     CWinCX *pContext = GetContext();
  2390.     if ( pContext && !m_imebool) { //added check for IME composition
  2391.         pCmdUI->Enable( CAN_INTERACT && EDT_COP_OK == EDT_CanCopy(pContext->GetContext(), FALSE));
  2392.     } else { 
  2393.         pCmdUI->Enable(FALSE);
  2394.     }
  2395. }
  2396.  
  2397. // Used only for Edit views
  2398. void CNetscapeEditView::OnUpdateEditPaste(CCmdUI* pCmdUI)
  2399. {
  2400.     MWContext *pMWContext = GET_MWCONTEXT;
  2401.     if( pMWContext && EDT_IS_EDITOR(pMWContext) && 
  2402.         !pMWContext->waitingMode && !EDT_IsBlocked(pMWContext)  &&
  2403.         !m_imebool){//added check for IME composition
  2404.         // Check if any of our supported formats is in the clipboard
  2405.         int iClip = GetPriorityClipboardFormat(m_pClipboardFormats, MAX_CLIPBOARD_FORMATS);
  2406.         pCmdUI->Enable( iClip != 0 && iClip != -1 && 
  2407.                         EDT_COP_OK == EDT_CanPaste(pMWContext, TRUE) );
  2408.     } else { 
  2409.         pCmdUI->Enable(FALSE);
  2410.     }
  2411. }
  2412.  
  2413. // The old-fashioned Method works for Win3.x and NT3.5,
  2414. // Only Win95 does OLE dragNdrop from file manager
  2415. void CNetscapeEditView::DropFiles( HDROP hDropInfo, BOOL bGetDropPoint)
  2416. {
  2417.     MWContext *pMWContext = NULL;
  2418.     if( GetContext() ){
  2419.         pMWContext = GetContext()->GetContext();
  2420.     }
  2421.     if( pMWContext == NULL ){
  2422.         return;
  2423.     }
  2424.  
  2425.     if( bGetDropPoint ){
  2426.         POINT pointDrop;
  2427.         // Get mouse at time of drop
  2428.         DragQueryPoint( hDropInfo, &pointDrop);
  2429.         // Drop Message went to frame,
  2430.         //  convert to doc coordinates
  2431.         //  (frame->screen->view->doc)
  2432.         GetParentFrame()->ClientToScreen( &pointDrop );
  2433.         ScreenToClient( &pointDrop );        
  2434.         int32 xVal, yVal;        
  2435.         CPoint cpDrop(pointDrop);
  2436.         ClientToDocXY( cpDrop, &xVal, &yVal );        
  2437.         EDT_PositionCaret( pMWContext, xVal, yVal );
  2438.     }
  2439.     
  2440.     // We accept HTML for link creation,
  2441.     // GIF and JPG for image insertion
  2442.     char pFilename[1024];
  2443.     // This is where we put image data
  2444.     EDT_ImageData* pEdtData = EDT_NewImageData();
  2445.  
  2446.     int iFileCount = DragQueryFile(hDropInfo, (UINT)-1, NULL,0);
  2447.  
  2448.     // Can't handle > 1 images at a time
  2449.     // TODO: TEST IF WE CAN DO > 1 IMAGE SINCE WE DON'T DO FILE SAVE UNTIL LATER!
  2450.     BOOL bImageInserted = FALSE;
  2451.     for ( int i = 0; i < iFileCount; i++ ) {
  2452.         if ( DragQueryFile(hDropInfo, i, pFilename, 1024) ) {
  2453.             CString csFilename(pFilename);
  2454.             int iLastDot = csFilename.ReverseFind('.');
  2455.             if(iLastDot > 0){
  2456.                 CString csExt = csFilename.Mid(iLastDot);
  2457.                 if ( 0 == csExt.CompareNoCase(".htm") ||
  2458.                      0 == csExt.CompareNoCase(".html") ||
  2459.                      0 == csExt.CompareNoCase(".shtml") ) {
  2460.                     // Use filename to paste a link
  2461.                     // Convert to relative URL
  2462.                     int bKeepLinks;
  2463.                     PREF_GetBoolPref("editor.publish_keep_links",&bKeepLinks);
  2464.                     if ( FE_ResolveLinkURL(pMWContext, csFilename, bKeepLinks) ){
  2465.                         char * pRelative = (char*)LPCSTR(csFilename);
  2466.                         EDT_PasteHREF( pMWContext, &pRelative, &pRelative, 1 );
  2467.                     }
  2468.                 }
  2469.                 else if( CanSupportImageFile(LPCSTR(csExt))  &&
  2470.                           !bImageInserted ){    // Only allow 1 inserted image
  2471.                     if (0 == csExt.CompareNoCase(".bmp"))
  2472.                     {
  2473. #ifdef _IMAGE_CONVERT
  2474.                         //need to convert bmp to xxx
  2475.                         CONVERT_IMGCONTEXT imageContext;
  2476.                         CONVERT_IMG_INFO imageInfo;
  2477.                         memset(&imageContext,0,sizeof(CONVERT_IMGCONTEXT));
  2478.                         imageContext.m_stream.m_type=CONVERT_FILE;
  2479.                         imageContext.m_stream.m_file=XP_FileOpen(pFilename,xpTemporary,XP_FILE_READ_BIN);
  2480.                         XP_STRCPY(imageContext.m_filename,pFilename);/* used for output filename creation*/
  2481.                         if (imageContext.m_stream.m_file)
  2482.                         {
  2483.                             imageContext.m_imagetype=conv_bmp;
  2484.                             imageContext.m_callbacks.m_dialogimagecallback=FE_ImageConvertDialog;
  2485.                             imageContext.m_callbacks.m_displaybuffercallback=FE_ImageConvertDisplayBuffer;
  2486.                             imageContext.m_callbacks.m_completecallback=FE_ImageDoneCallBack;
  2487.  
  2488.                             imageContext.m_pMWContext=pMWContext;
  2489.                             imageContext.m_parentwindow=(void *)this;
  2490.                             CONVERT_IMAGERESULT result=convert_stream2image(imageContext,&imageInfo,1,NULL);//1 for 1 output, NULL is for outputfile names we dont need.
  2491.                             //there is a callback when complete 
  2492.                             XP_FileClose(imageContext.m_stream.m_file);
  2493.                             if (result>CONV_OK)//not cancel or ok
  2494.                             {
  2495.                                 AfxMessageBox(m_converrmsg[result]);
  2496.                             }
  2497.                         }
  2498. #endif //IMAGE_CONVERT
  2499.                     }
  2500.                     else
  2501.                     {
  2502.                         WFE_ConvertFile2Url(csFilename, (const char*)pFilename);
  2503.                         pEdtData->pSrc = XP_STRDUP(csFilename);
  2504.                         // Paste the image file:
  2505.                         if ( pEdtData->pSrc ) {
  2506.                             int bKeepImages;
  2507.                             PREF_GetBoolPref("editor.publish_keep_images",&bKeepImages);
  2508.  
  2509.                             EDT_InsertImage(pMWContext, pEdtData,bKeepImages);
  2510.                             XP_FREE(pEdtData->pSrc);
  2511.                             pEdtData->pSrc = NULL;
  2512.                             bImageInserted = TRUE;
  2513.                         }
  2514.                     }
  2515.                 }
  2516.             } 
  2517.         }
  2518.     }
  2519.     EDT_FreeImageData(pEdtData);
  2520.  
  2521.     // We're done -- release data
  2522.     ::DragFinish( hDropInfo );
  2523. }
  2524.  
  2525. void CNetscapeEditView::OnEditBarToggle()
  2526. {
  2527.     GetFrame()->GetChrome()->ShowToolbar(IDS_EDIT_TOOLBAR_CAPTION,
  2528.                                          !GetFrame()->GetChrome()->GetToolbarVisible(IDS_EDIT_TOOLBAR_CAPTION));
  2529. }
  2530.  
  2531. void CNetscapeEditView::OnCharacterBarToggle()
  2532. {
  2533.     GetFrame()->GetChrome()->ShowToolbar(IDS_CHAR_TOOLBAR_CAPTION,
  2534.                                          !GetFrame()->GetChrome()->GetToolbarVisible(IDS_CHAR_TOOLBAR_CAPTION));
  2535. }
  2536.  
  2537. void CNetscapeEditView::OnUpdateEditBarToggle(CCmdUI* pCmdUI)
  2538. {
  2539.     if( pCmdUI->m_pMenu ){
  2540.         pCmdUI->m_pMenu->ModifyMenu(ID_OPT_EDITBAR_TOGGLE, MF_BYCOMMAND | MF_STRING, ID_OPT_EDITBAR_TOGGLE,
  2541.                                     szLoadString(CASTUINT(GetFrame()->GetChrome()->GetToolbarVisible(IDS_EDIT_TOOLBAR_CAPTION) ?
  2542.                                                  IDS_HIDE_EDITBAR : IDS_SHOW_EDITBAR)) );
  2543.         pCmdUI->Enable(CAN_INTERACT);
  2544.     }
  2545. }
  2546.  
  2547. void CNetscapeEditView::OnUpdateCharacterBarToggle(CCmdUI* pCmdUI)
  2548. {
  2549.     if( pCmdUI->m_pMenu ){
  2550.         pCmdUI->m_pMenu->ModifyMenu(ID_OPT_CHARBAR_TOGGLE, MF_BYCOMMAND | MF_STRING, ID_OPT_CHARBAR_TOGGLE,
  2551.                                     szLoadString(CASTUINT(GetFrame()->GetChrome()->GetToolbarVisible(IDS_CHAR_TOOLBAR_CAPTION) ?
  2552.                                                  IDS_HIDE_FORMATBAR : IDS_SHOW_FORMATBAR)) );
  2553.         pCmdUI->Enable(CAN_INTERACT);
  2554.     }
  2555. }
  2556.  
  2557. //////////////////////////////////////////////////////////////////////
  2558. // File/DOC-Save functions
  2559. //////////////////////////////////////////////////////////////////////
  2560.  
  2561. // We need to save current changes even though
  2562. //   we are opening a new Browser window
  2563. //   so the browser shows recent changes
  2564. void CNetscapeEditView::OnOpenNavigatorWindow()
  2565. {
  2566.     MWContext * pMWContext = GET_MWCONTEXT;
  2567.     if( !pMWContext || !EDT_IS_EDITOR(pMWContext) ){
  2568.         return;
  2569.     }
  2570.     // Force saving (or don't continue) if new document,
  2571.     //  or ask user to save first 
  2572.     if( !FE_SaveDocument(pMWContext) ){
  2573.         return;
  2574.     }
  2575.     ((CGenericFrame*)GetParentFrame())->OpenNavigatorWindow(pMWContext);
  2576. }
  2577.  
  2578. //
  2579. // Prompt the user for a file name where we should store this document
  2580. //
  2581. void CNetscapeEditView::OnFileSaveAs()
  2582. {
  2583.     int bKeepImages;
  2584.     PREF_GetBoolPref("editor.publish_keep_images",&bKeepImages);
  2585.     int bKeepLinks;
  2586.     PREF_GetBoolPref("editor.publish_keep_links",&bKeepLinks);
  2587.  
  2588.     SaveDocumentAs( bKeepImages,bKeepLinks );
  2589. }
  2590.  
  2591. void CNetscapeEditView::OnUpdateFileSave(CCmdUI* pCmdUI)
  2592. {
  2593.     pCmdUI->Enable(CAN_INTERACT && EDT_DirtyFlag(GET_MWCONTEXT));
  2594. }
  2595.  
  2596. // Call the front end after every Autosave event so toolbar SAVE button can be grayed
  2597. void FE_UpdateEnableStates(MWContext * pMWContext)
  2598. {
  2599.     CGenericFrame * pFrame = (CGenericFrame*)GetFrame(pMWContext);
  2600.     if( pFrame )
  2601.     {
  2602.         // This triggers update of all UI components
  2603.         CNetscapeApp::SendMessageToDescendants(pFrame->m_hWnd, 
  2604.                                     WM_IDLEUPDATECMDUI, (WPARAM)TRUE, (LPARAM)0);
  2605.     }
  2606. }
  2607.  
  2608. BOOL CNetscapeEditView::SaveDocumentAs(BOOL bKeepImagesWithDoc,
  2609.                                        BOOL bAutoAdjustLinks )
  2610. {
  2611.     BOOL bRetVal = TRUE;
  2612.     if(GetContext() )    // GetActiveContext())
  2613.     {
  2614.         MWContext * pMWContext = GET_MWCONTEXT;
  2615.         if ( pMWContext == NULL ) {
  2616.             return FALSE;
  2617.         }
  2618.         History_entry * hist_entry = SHIST_GetCurrent(&(pMWContext->hist));
  2619.         if(hist_entry && hist_entry->address)
  2620.         {
  2621.             int  iType = HTM_ONLY;    // This restricts filter to "*.htm;*.html"
  2622.             char *pSuggested = NULL;
  2623.  
  2624.             // Try to suggest a name if not a new doc or local directory)
  2625.             if ( !EDT_IS_NEW_DOCUMENT(pMWContext) ) {
  2626.                 if ( NET_IsLocalFileURL(hist_entry->address ) ) {
  2627.                     // Supply full pathname for a local URL
  2628.                        XP_ConvertUrlToLocalFile( hist_entry->address, &pSuggested );
  2629.                 } else {
  2630.                     // What we really want is an attempt to get 8+3 filename
  2631.                     //   from the URL, but there are many cases when this will be NULL:
  2632.                     //   then dialog uses "*.htm; *.html" as name
  2633.                     pSuggested = fe_URLtoLocalName(hist_entry->address, NULL);
  2634.                 }
  2635.             }
  2636.         GET_SAVEAS_FILENAME:
  2637.             char *pLocalFile = wfe_GetSaveFileName(GET_DLG_PARENT(this)->m_hWnd,
  2638.                                      szLoadString(IDS_SAVE_AS_CAPTION), pSuggested, &iType, NULL/*ppTitle*/);
  2639.             if ( pSuggested ) {
  2640.                 XP_FREE(pSuggested);
  2641.             }
  2642.             pSuggested = NULL;
  2643.  
  2644.             if ( pLocalFile ) {
  2645.                 HCURSOR hOldCursor = 0;
  2646.                 if( iType == TXT )
  2647.                 {
  2648.                     hOldCursor = SetCursor(theApp.LoadStandardCursor(IDC_WAIT));
  2649.                     SaveDocumentAsText(pLocalFile);
  2650.                 } else {
  2651.                     EDT_PageData * pPageData = EDT_GetPageData(pMWContext);
  2652.                     // Prompt for the Page Title if it doesn't exist
  2653.                     // ( Extending common dialog for Save File is too much of a pain:
  2654.                     //   Had display errors in Win versions 4+ and to much work for Win16 and Win3.51! )
  2655.                     if( pPageData){
  2656.                         if( !pPageData->pTitle || pPageData->pTitle[0] == '\0'){
  2657.                             XP_FREEIF(pPageData->pTitle);
  2658.                             pPageData->pTitle = EDT_GetPageTitleFromFilename(pLocalFile);
  2659.                             CPageTitleDlg dlg(this, &pPageData->pTitle);
  2660.                             if( dlg.DoModal() == IDOK ){
  2661.                                 EDT_SetPageData(pMWContext, pPageData);
  2662.                                 // (Note: This triggers changing Title everywhere that is needed)
  2663.                             }
  2664.                         }
  2665.                         EDT_FreePageData(pPageData);
  2666.                     }
  2667.  
  2668.                     CString csUrlFileName; 
  2669.                     // EDT_ is cross-platform - convert to URL format
  2670.                     WFE_ConvertFile2Url(csUrlFileName, (const char*)pLocalFile);
  2671.                     char * szURL = (char*)(LPCTSTR(csUrlFileName));
  2672.  
  2673.                     // Check if this file is already being edited in another edit frame(+context)
  2674.                     for(CGenericFrame * f = theApp.m_pFrameList; f; f = f->m_pNext) {
  2675.                         MWContext *pOtherContext = f->GetMainContext()->GetContext();
  2676.                         if ( pOtherContext && EDT_IS_EDITOR(pOtherContext) &&
  2677.                              pOtherContext != pMWContext ) {
  2678.                 
  2679.                             History_entry * pEntry = SHIST_GetCurrent(&pOtherContext->hist);
  2680.                             if( pEntry && pEntry->address &&
  2681.                                 0 == XP_STRCMP(pEntry->address, szURL ) ) {
  2682.                                 // User selected a file they were editing in 
  2683.                                 //   a different buffer!  Get further confirmation:
  2684.                                 // Yes to overwrite, No to select a different name, 
  2685.                                 //   Cancel to abort editing
  2686.                                 CString csMsg;
  2687.                                 AfxFormatString1( csMsg, IDS_OVERWRITE_ACTIVE_FILE, szURL );  
  2688.                                 UINT nResult = MessageBox( csMsg, 
  2689.                                                            szLoadString(IDS_SAVE_AS_CAPTION),
  2690.                                                            MB_YESNOCANCEL | MB_ICONQUESTION );
  2691.                                 if ( nResult == IDNO ) {
  2692.                                     goto GET_SAVEAS_FILENAME;
  2693.                                 }
  2694.                                 if ( nResult == IDCANCEL ) {
  2695.                                     XP_FREE(pLocalFile);
  2696.                                     return FALSE;
  2697.                                 }
  2698.                                 break;
  2699.                             }
  2700.                         }
  2701.                     }
  2702.                     // If here, we are ready to save
  2703.                 
  2704.                     // Add the URL we are about to save to the history list
  2705.                     //   so user can browse back to it
  2706.                     // Add the original source URL to the history list so we can browse back
  2707.                     //   to it later. THIS COULD ALSO BE USED FOR PUBLISHING?
  2708.                     if( m_bSaveRemoteToLocal ){
  2709.                         m_csSourceUrl = hist_entry->address;
  2710.                         
  2711.                         // Round-about way of copying current history to a new one!
  2712.                         URL_Struct *pURL = SHIST_CreateURLStructFromHistoryEntry(pMWContext, hist_entry);
  2713.                         if ( pURL ) {
  2714.                             // Zero out the form etc. data else we double free it later
  2715.                             memset((void *)&(pURL->savedData), 0, sizeof(SHIST_SavedData));
  2716.                             
  2717.                             // Always check the server to get most up-to-date version
  2718.                             pURL->force_reload = NET_NORMAL_RELOAD;
  2719.  
  2720.                             // If there is no title, it will be set to URL address
  2721.                             ///  in CFE_FinishedLayout. It makes no sense to
  2722.                             //  use this title when changing the filename
  2723.                             char * pTitle = NULL;
  2724.                             if ( hist_entry->title == NULL || 
  2725.                                  XP_STRCMP(hist_entry->title, hist_entry->address) ) {
  2726.                                 pTitle = hist_entry->address;
  2727.                             }
  2728.  
  2729.                             History_entry * new_entry = SHIST_CreateHistoryEntry( pURL, pTitle); 
  2730.  
  2731.                             if( new_entry ){
  2732.                                 // Make sure we add a new one by changing post data
  2733.                                 //   and history number (must fool SHIST_AddDocument!);
  2734.                                 if(new_entry->post_data) XP_FREE(hist_entry->post_data);
  2735.                                 new_entry->post_data = XP_STRDUP("!");
  2736.                                 new_entry->post_data_size = 1;
  2737.                                 new_entry->history_num = 0;
  2738.  
  2739.                                 SHIST_AddDocument(pMWContext, new_entry);
  2740.  
  2741.                                 // Remove bogus post data
  2742.                                 XP_FREE(new_entry->post_data);
  2743.                                 new_entry->post_data = NULL;
  2744.                                 new_entry->post_data_size = 0;
  2745.                             }
  2746.                         }
  2747.                         m_bSaveRemoteToLocal = FALSE;
  2748.                     }
  2749.                     hOldCursor = SetCursor(theApp.LoadStandardCursor(IDC_WAIT));
  2750.                 
  2751.                     ED_FileError nResult = EDT_SaveFile(pMWContext, 
  2752.                                                  hist_entry->address,             // Source
  2753.                                                  szURL,                         // Destination
  2754.                                                  TRUE,                          // Do SaveAs
  2755.                                                  bKeepImagesWithDoc,
  2756.                                                  bAutoAdjustLinks);
  2757.  
  2758.                     if( nResult == ED_ERROR_NONE ){
  2759.                         //  Spin the message loop and network until the
  2760.                         //  asynchronous file save procedure has finished
  2761.                         //  The final error status will be written to m_FileSaveStatus
  2762.                         //    when the SaveFile dialog is destroyed.
  2763.                         while( m_pSaveFileDlg ){
  2764.                             FEU_StayingAlive();
  2765.                             // Note: this seems to work as well - which is better?
  2766.                             // nettimer.OnIdle();
  2767.                         }
  2768.                         // Tell edit core the file Auto Save preference
  2769.                         // Primary purpose is to reset autosave if user Canceled when
  2770.                         //  prompted to autosave a new doc (that sets AutoSave time to 0)
  2771.                         int32 iSave;
  2772.                         PREF_GetIntPref("editor.auto_save_delay",&iSave);
  2773.                         EDT_SetAutoSavePeriod(pMWContext, iSave );
  2774.  
  2775.                         // Return TRUE only if we actually saved, or user said NO,
  2776.                         //  but return FALSE if they Canceled or other error.
  2777.                         if ( m_FileSaveStatus == ED_ERROR_NONE ) {
  2778. #ifdef XP_WIN32
  2779.                             if( bSiteMgrIsActive ) {
  2780.                                 // Tell SiteManager we saved a file
  2781.                                 pITalkSMClient->SavedURL(pLocalFile);
  2782.                             }
  2783.                         
  2784.                             if( sysInfo.m_bWin4 || sysInfo.m_dwMajor == 4 ){
  2785.                                 // Add file to Win95 Shell's Documents menu
  2786.                                 SHAddToRecentDocs( SHARD_PATH, pLocalFile );
  2787.                             }
  2788. #endif
  2789.                         } else 
  2790.                             bRetVal = FALSE;  // Error at end of save
  2791.                     } else
  2792.                         bRetVal = FALSE;      // Error during start of save
  2793.                 }
  2794.                 if (pLocalFile){
  2795.                     XP_FREE(pLocalFile);
  2796.                 }
  2797.                 if( hOldCursor )
  2798.                     SetCursor(hOldCursor);
  2799.  
  2800.            } else bRetVal = FALSE;       // No local file (user canceled)
  2801.         
  2802.         } // Note: end of "we have a current history entry" Should we return FALSE if not?
  2803.     }
  2804.     return bRetVal; // Default = TRUE
  2805. }
  2806.  
  2807. void CNetscapeEditView::OnFileSave()
  2808. {
  2809.     SaveDocument();
  2810. }
  2811.  
  2812. BOOL CNetscapeEditView::SaveDocument()
  2813. {
  2814.     BOOL bRetVal = TRUE;
  2815.     if(GetContext())
  2816.     {
  2817.         MWContext * pMWContext = GET_MWCONTEXT;
  2818.         if( !pMWContext ){
  2819.             return TRUE;
  2820.         }
  2821.         History_entry * hist_entry = SHIST_GetCurrent(&(pMWContext ->hist));
  2822.  
  2823.         if(hist_entry && hist_entry->address)
  2824.         {
  2825.             char *pLocalFile = NULL;
  2826.  
  2827.             // TODO: Current model does local SaveAs for all new pages - 
  2828.             //       have pref to use Publish as default?
  2829.  
  2830.             if ( !EDT_IS_NEW_DOCUMENT(pMWContext ) )
  2831.             {
  2832.                    if( XP_ConvertUrlToLocalFile( hist_entry->address, &pLocalFile ) )
  2833.                 {
  2834.                     int bKeepImages;
  2835.                     PREF_GetBoolPref("editor.publish_keep_images",&bKeepImages);
  2836.                     int bKeepLinks;
  2837.                     PREF_GetBoolPref("editor.publish_keep_links",&bKeepLinks);
  2838.  
  2839.                     HCURSOR hOldCursor = SetCursor(theApp.LoadStandardCursor(IDC_WAIT));
  2840.                     ED_FileError nResult = EDT_SaveFile(pMWContext ,hist_entry->address,  // Source
  2841.                                                 hist_entry->address,        // Destination
  2842.                                                 FALSE,                      // Not doing "SaveAs"
  2843.                                                 bKeepImages, bKeepLinks);
  2844.             
  2845.                     if( nResult == ED_ERROR_NONE ){
  2846.                         //  Spin the message loop and network until the
  2847.                         //  asynchronous file save procedure has finished
  2848.                         //  The final error status will be written to m_FileSaveStatus
  2849.                         //    when the SaveFile dialog is destroyed.
  2850.                         // Because of asynchronous Composer Plugin hook, 
  2851.                         //   CSaveDialog is not created after return from EDT_SaveFile,
  2852.                         //   so check the context flag as well. That flag is cleared 
  2853.                         //   near end of saving, so checking for m_pSaveFileDlg also
  2854.                         //   makes sure everything is done before continuing.
  2855.                         //   This is important for maintaining proper window focus 
  2856.                         while( pMWContext->edit_saving_url || m_pSaveFileDlg ){
  2857.                             FEU_StayingAlive();
  2858.                             // Note: this seems to work as well
  2859.                             // nettimer.OnIdle();
  2860.                         }
  2861.                         // Return TRUE only if we actually saved, or user said NO,
  2862.                         //  but return FALSE if they Canceled or other error.
  2863.                         if ( m_FileSaveStatus == ED_ERROR_NONE ) {
  2864.     #ifdef XP_WIN32
  2865.                             if( bSiteMgrIsActive ) {
  2866.                                 // Tell SiteManager we saved a file
  2867.                                 pITalkSMClient->SavedURL(pLocalFile);
  2868.                             }
  2869.                             if( sysInfo.m_bWin4 || sysInfo.m_dwMajor == 4 ){
  2870.                                 // Add file to Win95 Shell's Documents menu
  2871.                                 SHAddToRecentDocs( SHARD_PATH, pLocalFile );
  2872.                             }
  2873.     #endif
  2874.                         } else 
  2875.                             bRetVal = FALSE;  // Error at end of save
  2876.                     } else
  2877.                         bRetVal = FALSE;      // Error during start of save
  2878.  
  2879.                     if (pLocalFile){
  2880.                         XP_FREE(pLocalFile);
  2881.                     }
  2882.                     SetCursor(hOldCursor);
  2883.                     return bRetVal;
  2884.                 }
  2885.             }
  2886.             // If we didn't save above, fall through to do SaveAs
  2887.             //  (new page or unknown URL type)
  2888.             int bKeepImages;
  2889.             PREF_GetBoolPref("editor.publish_keep_images",&bKeepImages);
  2890.             int bKeepLinks;
  2891.             PREF_GetBoolPref("editor.publish_keep_links",&bKeepLinks);
  2892.  
  2893.             return SaveDocumentAs( bKeepImages,bKeepLinks );
  2894.         } // Note: end of "we have a current history entry" Should we return FALSE if not?
  2895.     }
  2896.     return bRetVal; // Default = TRUE
  2897. }
  2898.  
  2899. // To prevent recursion
  2900. static BOOL bCheckAndSave = FALSE;
  2901.  
  2902. // This doesn't prompt to save file if a new document
  2903. // Use FE_SaveDocument when we must save the new document even if not dirty
  2904. BOOL CheckAndSaveDocument(MWContext * pMWContext, BOOL bAutoSaveNewDoc) 
  2905. {
  2906.     if ( bCheckAndSave ||
  2907.          pMWContext == NULL ||
  2908.          !EDT_IS_EDITOR(pMWContext) ||
  2909.          !EDT_HaveEditBuffer(pMWContext) ||
  2910.          pMWContext->type == MWContextMessageComposition){
  2911.         return TRUE;
  2912.     }
  2913.     // Get the edit view
  2914.     CNetscapeEditView* pView = (CNetscapeEditView*)WINCX(pMWContext)->GetView();
  2915.     if ( !pView->IsKindOf(RUNTIME_CLASS(CNetscapeEditView))) {
  2916.         return TRUE;
  2917.     }
  2918.     // Skip autosave prompt for new page if it is not the window with focus
  2919.     //  This avoids popping up AutoSave dialog when in other windows
  2920.     if( bAutoSaveNewDoc && pView != pView->GetFocus() ){
  2921.         TRACE0("Skipping Autosave of new doc - View not in focus\n");
  2922.         return TRUE;
  2923.     }
  2924.  
  2925.     BOOL bRetVal = TRUE;
  2926.  
  2927.     // Set flag to prevent recursive call
  2928.     bCheckAndSave = TRUE;
  2929.  
  2930.     History_entry * hist_entry = SHIST_GetCurrent(&(pMWContext->hist));
  2931.     if( hist_entry && hist_entry->address &&  
  2932.         ( /*EDT_IS_NEW_DOCUMENT(pMWContext) ||*/ EDT_DirtyFlag(pMWContext) ) )   //BIG CHANGE
  2933.     {
  2934.         CString csSavePrompt;
  2935.         if ( EDT_IS_NEW_DOCUMENT(pMWContext) ) {
  2936.             AfxFormatString1( csSavePrompt, IDS_SAVE_DOC_PROMPT, EDT_NEW_DOC_NAME );  
  2937.         } else { 
  2938.             char * pLocalFile = NULL;
  2939.             CString csName;
  2940.             // Change URL name to local filename format
  2941.             //  returns true if it local file was found
  2942.             if ( XP_ConvertUrlToLocalFile( hist_entry->address, &pLocalFile) ) {
  2943.                 // We are editing a local file
  2944.                 csName = pLocalFile;
  2945.                 XP_FREE( pLocalFile );
  2946.             } else {    
  2947.                 // We edited a non-local document
  2948.                 // TODO: ADD NEW DIALOG TO GIVE USER CHOICE OF SAVING LOCALLY OR PUBLISHING
  2949.                 // IDS_SAVE_HTTP_PROMPT was used for old behavior. Modify and use here
  2950.                 csName = hist_entry->address;
  2951.             }
  2952.             // Don't let the name get too big!
  2953.             WFE_CondenseURL(csName, 50, FALSE);
  2954.             AfxFormatString1( csSavePrompt, IDS_SAVE_DOC_PROMPT, LPCSTR(csName));  
  2955.         }
  2956.         if( bAutoSaveNewDoc ){
  2957.             csSavePrompt += "\n";
  2958.             csSavePrompt += szLoadString(IDS_AUTOSAVE_OFF_MSG );
  2959.         }
  2960.  
  2961.         char *pCaption = szLoadString(CASTUINT(bAutoSaveNewDoc ? IDS_AUTOSAVE_CAPTION : AFX_IDS_APP_TITLE));
  2962.         int nSaveDoc = GET_DLG_PARENT(pView)->MessageBox( LPCSTR(csSavePrompt), pCaption,
  2963.                                           MB_YESNOCANCEL | MB_ICONQUESTION );
  2964.         if( nSaveDoc == IDCANCEL ){
  2965.             bRetVal = FALSE;
  2966.         } else if( nSaveDoc == IDYES &&
  2967.                    !pView->SaveDocument() ) {
  2968.             // Use changed their mind and cancelled out of SaveAs Dialog
  2969.             bRetVal = FALSE;
  2970.         }
  2971.     }
  2972.  
  2973.     bCheckAndSave = FALSE;
  2974.     return bRetVal;
  2975. }
  2976.  
  2977. // A cross between SaveDocument() and OnPublish()
  2978. // Return TRUE only if we actually save the files
  2979. BOOL CNetscapeEditView::SaveRemote()
  2980. {
  2981.     MWContext * pMWContext = GET_MWCONTEXT;
  2982.     if(pMWContext == NULL)
  2983.         return FALSE;
  2984.  
  2985.     History_entry * hist_entry = SHIST_GetCurrent(&(pMWContext ->hist));
  2986.  
  2987.     BOOL bRetVal = FALSE;
  2988.  
  2989.     if(hist_entry || hist_entry->address)
  2990.     {   
  2991.         int    nType = NET_URL_Type(hist_entry->address);
  2992.         if( nType == FTP_TYPE_URL ||
  2993.             HTTP_TYPE_URL         ||
  2994.             SECURE_HTTP_TYPE_URL )
  2995.         {
  2996.             ED_SaveFinishedOption finishedOpt = ED_FINISHED_REVERT_BUFFER;
  2997.             XP_Bool *pSelectedDefault;
  2998.  
  2999.             // Publishing location is just current URL without filename, so strip it off
  3000.             char * pLocation = EDT_ReplaceFilename(hist_entry->address, NULL, TRUE);
  3001.             if( pLocation )
  3002.             {
  3003.                 // Get Pulishing params from preferences
  3004.                 int bKeepImages;
  3005.                 PREF_GetBoolPref("editor.publish_keep_images",&bKeepImages);
  3006.                 int bKeepLinks;
  3007.                 PREF_GetBoolPref("editor.publish_keep_links",&bKeepLinks);
  3008.                 XP_Bool bRemberPassword;
  3009.                 PREF_GetBoolPref("editor.publish_save_password",&bRemberPassword);
  3010.         
  3011.                 // Get list of included image files with respective "leave image at original location" values
  3012.                 char * pIncludedFiles = EDT_GetAllDocumentFilesSelected( pMWContext, &pSelectedDefault, bKeepImages );
  3013.  
  3014.                 // Convert from ASIIZ format to an array of strings
  3015.                 char **ppIncludedFiles = NULL;
  3016.  
  3017.                 if( pIncludedFiles )
  3018.                 {
  3019.                     int iFileCount = 0;
  3020.  
  3021.                     char * pString = pIncludedFiles;
  3022.                     int iLen;    
  3023.  
  3024.                     // Scan list once to count items
  3025.                     while( (iLen = XP_STRLEN(pString)) > 0 )
  3026.                     {
  3027.                         pString += iLen+1;
  3028.                         iFileCount++;
  3029.                     }
  3030.                     if( iFileCount )
  3031.                     {
  3032.                         ppIncludedFiles = (char**)XP_ALLOC((iFileCount+1) * sizeof(char*));
  3033.  
  3034.                         if(ppIncludedFiles)
  3035.                         {
  3036.                             pString = pIncludedFiles;
  3037.                             for( int i = 0; i< iFileCount; i++)
  3038.                             {
  3039.                                 ppIncludedFiles[i] = XP_STRDUP(pString);
  3040.                                 pString += XP_STRLEN(pString) + 1;
  3041.                             }
  3042.                             // Terminate the list
  3043.                             ppIncludedFiles[i] = NULL;
  3044.                         }
  3045.                     }
  3046.                     XP_FREE(pIncludedFiles);
  3047.                 }                
  3048.                 
  3049.                 ED_FileError nResult =  
  3050.                                 EDT_PublishFile(pMWContext,finishedOpt, hist_entry->address, 
  3051.                                                 ppIncludedFiles, 
  3052.                                                 pLocation,
  3053.                                                 bKeepImages,
  3054.                                                 bKeepLinks,
  3055.                                                 bRemberPassword);
  3056.                 if( nResult == ED_ERROR_NONE )
  3057.                 {
  3058.                     //  Spin the message loop and network until the
  3059.                     //  asynchronous file save procedure has finished
  3060.                     //  The final error status will be written to m_FileSaveStatus
  3061.                     //    when the SaveFile dialog is destroyed.
  3062.                     while( m_pSaveFileDlg ){
  3063.                         FEU_StayingAlive();
  3064.                     }
  3065.                     // Return TRUE only if we actually saved, or user said NO,
  3066.                     //  but return FALSE if they Canceled or other error.
  3067.                     if ( m_FileSaveStatus == ED_ERROR_NONE )
  3068.                     {
  3069.                         bRetVal = TRUE;
  3070.     #ifdef XP_WIN32
  3071.                         if( bSiteMgrIsActive )
  3072.                         {
  3073.                             // Tell SiteManager we saved a file
  3074.                             pITalkSMClient->SavedURL(hist_entry->address);
  3075.                         }
  3076.  
  3077.                         /*  TODO: Should we add URLs to Window's document list?
  3078.                         if( sysInfo.m_bWin4 || sysInfo.m_dwMajor == 4 ){
  3079.                             // Add file to Win95 Shell's Documents menu
  3080.                             SHAddToRecentDocs( SHARD_PATH, hist_entry->address );
  3081.                         }*/
  3082.     #endif
  3083.                     }
  3084.                 }
  3085.  
  3086.                 XP_FREE(pLocation);
  3087.                 //NOTE: DO NOT try to free ppIncludedFiles list - EDT_PublishFile will do that
  3088.  
  3089.                 // Stay here untill file upload has finished
  3090.                 while( m_pSaveFileDlg )
  3091.                     FEU_StayingAlive();
  3092.             }
  3093.         }
  3094.     }
  3095.  
  3096.     return bRetVal;
  3097. }
  3098.  
  3099. void CNetscapeEditView::OnPublish() 
  3100. {
  3101.     MWContext * pMWContext = GET_MWCONTEXT;
  3102.     if(pMWContext == NULL) {
  3103.         return;
  3104.     }
  3105.  
  3106.     char *pSrcURL;
  3107.     History_entry * pEntry = SHIST_GetCurrent(&pMWContext->hist);
  3108.     if (pEntry && pEntry->address && *pEntry->address) {
  3109.       pSrcURL = XP_STRDUP(pEntry->address);
  3110.     }
  3111.     else {
  3112.       // no source name.
  3113.       pSrcURL = XP_STRDUP(EDT_NEW_DOC_NAME);
  3114.     }
  3115.  
  3116.     // Get the destination and what files to include from the user
  3117.     // Pass in the URL of the last-failed publishing attempt
  3118.     //  so it can use the last-location prefs and correct typing errors
  3119.     CPublishDlg dlg(this, pMWContext, pSrcURL);
  3120.  
  3121.     if( IDOK == dlg.DoModal() ) {
  3122.         int bKeepImages;
  3123.         PREF_GetBoolPref("editor.publish_keep_images",&bKeepImages);
  3124.         int bKeepLinks;
  3125.         PREF_GetBoolPref("editor.publish_keep_links",&bKeepLinks);
  3126.  
  3127.         EDT_PublishFile(pMWContext,ED_FINISHED_REVERT_BUFFER, pSrcURL, 
  3128.                         dlg.m_ppIncludedFiles, 
  3129.                         dlg.m_pFullLocation,
  3130.                         bKeepImages,
  3131.                         bKeepLinks,
  3132.                         dlg.m_bRememberPassword);
  3133.     }
  3134.  
  3135.     XP_FREE(pSrcURL);
  3136. }
  3137.  
  3138. // USE BROWSER'S SAVE MECHANISM FOR TEXT FILES
  3139. void EdtSaveToTempCallback( char *pFileURL, void *hook )
  3140. {
  3141.     MWContext *pMWContext = (MWContext*)hook;
  3142.     if( pMWContext )
  3143.     {
  3144.         // Get the edit view
  3145.         CNetscapeEditView* pView = (CNetscapeEditView*)WINCX(pMWContext)->GetView();
  3146.         if ( !pView->IsKindOf(RUNTIME_CLASS(CNetscapeEditView)))
  3147.         {
  3148.             XP_ASSERT(0);    
  3149.             return;
  3150.         }
  3151.  
  3152.         // Clear any existing name
  3153.         XP_FREEIF( pView->m_pTempFilename );
  3154.  
  3155.         if( pFileURL )
  3156.         {
  3157.             pView->m_pTempFilename = XP_STRDUP(pFileURL);
  3158.         }
  3159.     }
  3160. }
  3161.  
  3162. char* CNetscapeEditView::SaveToTempFile()
  3163. {
  3164.     MWContext *pMWContext = GET_MWCONTEXT;
  3165.     if( pMWContext )
  3166.     {
  3167.         History_entry * hist_entry = SHIST_GetCurrent(&(pMWContext->hist));
  3168.         if(hist_entry && hist_entry->address)
  3169.         {
  3170.             EDT_SaveToTempFile(pMWContext, EdtSaveToTempCallback, pMWContext);
  3171.  
  3172.             // Spin here until temp file saving is finished
  3173.             while(  pMWContext->edit_saving_url ) 
  3174.             {
  3175.                 FEU_StayingAlive();
  3176.             }
  3177.  
  3178.             // Note: All temp files are automatically deleted when we exit the app
  3179.             return m_pTempFilename;
  3180.         }
  3181.     }
  3182.     return NULL;
  3183. }
  3184.  
  3185. // Klude so we don't have to include cxsave.h to access CSaveCX::SaveAnchorAsText
  3186. // (Win16 compiler runs out of keys if we include cxsave.h)
  3187. extern BOOL wfe_SaveAnchorAsText(const char *pAnchor, History_entry *pHist,  CWnd *pParent, char *pFileName);
  3188.  
  3189. void CNetscapeEditView::SaveDocumentAsText(char * pFilename)
  3190. {
  3191.     MWContext *pMWContext = GET_MWCONTEXT;
  3192.     if( ! pMWContext || !pFilename )
  3193.         return;
  3194.  
  3195.     if( EDT_DirtyFlag(pMWContext) || EDT_IS_NEW_DOCUMENT(pMWContext) )
  3196.     {
  3197.         // First save current page as temp HTML file
  3198.         char *pTempFilename = SaveToTempFile();
  3199.         if(  pTempFilename )
  3200.         {
  3201.             // This saving is ASYNCHRONOUS, but isn't a problem since its
  3202.             //   doesn't affect what we edit - we don't switch to editing this
  3203.             //   content like we do when doing SaveAs for HTML.
  3204.             wfe_SaveAnchorAsText(pTempFilename, NULL, this, pFilename);
  3205.         }
  3206.     } 
  3207.     else 
  3208.     {
  3209.             // No temp file needed - just use current file
  3210.         History_entry * hist_entry = SHIST_GetCurrent( &(pMWContext->hist) );
  3211.         if( hist_entry && hist_entry->address )
  3212.         {
  3213.             wfe_SaveAnchorAsText( hist_entry->address, NULL, this, pFilename );
  3214.         }
  3215.     }
  3216. }
  3217.  
  3218. ////////////////////////////////////////////////////////////////////////////////////
  3219. // Call this instead of forcing file saving by making 
  3220. //  a temporary file from current page. This filename
  3221. //  replaces the pUrl->address in struct passed in.
  3222. //  If return is FALSE, then there was an error - don't continue
  3223. BOOL FE_PrepareTempFileUrl(MWContext * pMWContext, URL_Struct *pUrl)
  3224. {
  3225.     if( EDT_IS_EDITOR(pMWContext) &&
  3226.         (pMWContext->bIsComposeWindow || EDT_IS_NEW_DOCUMENT(pMWContext) || EDT_DirtyFlag(pMWContext)) )
  3227.     {
  3228.         CNetscapeEditView* pView = (CNetscapeEditView*)WINCX(pMWContext)->GetView();
  3229.  
  3230.         if ( !pView || !pView->IsKindOf(RUNTIME_CLASS(CNetscapeEditView))) {
  3231.             return FALSE;
  3232.         }
  3233.         char *pTempFilename = pView->SaveToTempFile();
  3234.         if( pTempFilename )
  3235.         {
  3236.             XP_FREEIF(pUrl->address);
  3237.             pUrl->address = XP_STRDUP(pTempFilename);
  3238.         } else {
  3239.             // Failed to save to the temp file - abort
  3240.             return FALSE;            
  3241.         }
  3242.     }
  3243.     // If we don't need to change anything in the URL struct,
  3244.     //  just return that its OK
  3245.     return TRUE;
  3246. }
  3247.  
  3248. ////////////////////////////////////////////////////////////////////////////////////
  3249. // Check if changes were made, prompt user to save if they were
  3250. // Returns TRUE for all cases except CANCEL by the user in any dialog
  3251. BOOL FE_CheckAndSaveDocument(MWContext * pMWContext) 
  3252. {
  3253.     return CheckAndSaveDocument( pMWContext, FALSE );
  3254. }
  3255.  
  3256. BOOL FE_CheckAndAutoSaveDocument(MWContext * pMWContext) 
  3257. {
  3258.     return CheckAndSaveDocument( pMWContext, TRUE );
  3259. }
  3260.  
  3261. // Not used any more, but its declared in ns/include/fe_proto.h
  3262. BOOL FE_SaveNonLocalDocument(MWContext * pMWContext, BOOL bSaveNewDocument) 
  3263. {
  3264.     return TRUE;
  3265. }
  3266.  
  3267. // Call when we MUST save a NEW document, such as before Printing or calling an external Editor
  3268. // Return TRUE: 
  3269. //      1. User saved the document
  3270. //      2. User didn't want to save, and doc already exists (not new)
  3271. //      3. Doc exists but is not dirty
  3272. //      4. We are not a Page Composer (allows calling without testing for EDT_IS_EDITOR() first )
  3273. //      5. We are a Message Compose window
  3274. // Note: We must always save a new/untitled document, even if not dirty
  3275. BOOL FE_SaveDocument(MWContext * pMWContext)
  3276. {
  3277.     if( !pMWContext ){
  3278.         return FALSE;
  3279.     }
  3280.     if( !EDT_IS_EDITOR(pMWContext) ||
  3281.         pMWContext->type == MWContextMessageComposition){
  3282.         return TRUE;
  3283.     }
  3284.     if(EDT_IS_NEW_DOCUMENT(pMWContext) ){
  3285.         // Force saving a new document
  3286.         // WHO CHANGED THIS TO GetPane()? That fails!
  3287.         CNetscapeEditView* pView = (CNetscapeEditView*)WINCX(pMWContext)->GetView(); //GetPane();
  3288.         if ( !pView->IsKindOf(RUNTIME_CLASS(CNetscapeEditView))) {
  3289.             return TRUE;
  3290.         }
  3291.         CSaveNewDlg dlg( GET_DLG_PARENT(pView) );
  3292.         if ( dlg.DoModal() == IDOK ) {
  3293.             return pView->SaveDocument();
  3294.         }
  3295.    } else {
  3296.         // Doc is already saved - save again only if dirty and user wants to
  3297.         return FE_CheckAndSaveDocument(pMWContext);
  3298.     }
  3299.     return FALSE;
  3300. }
  3301.  
  3302. /////////////////////////////////////////////////////////////////////////////
  3303.  
  3304. // Use this for any item that just needs a context to be active
  3305. //   AND we are not in "waiting mode"
  3306. void CNetscapeEditView::HaveEditContext(CCmdUI* pCmdUI)
  3307. {
  3308.     pCmdUI->Enable(CAN_INTERACT);
  3309. }
  3310.  
  3311. // Use this for any item that is active if there is no selected text
  3312. void CNetscapeEditView::IsNotSelected(CCmdUI* pCmdUI)
  3313. {
  3314.     pCmdUI->Enable( CAN_INTERACT && !EDT_IsSelected(GET_MWCONTEXT) );
  3315. }
  3316.  
  3317. #ifdef _IMAGE_CONVERT
  3318.  
  3319.  
  3320.  
  3321.  
  3322. void
  3323. FE_ImageConvertPluginCallback(EDT_ImageEncoderStatus status, void* hook)
  3324. {
  3325.     PluginHookStruct *t_hook=(PluginHookStruct *)hook;
  3326.     if (ED_IMAGE_ENCODER_USER_CANCELED==status)
  3327.     {
  3328.         return;//nothing to do.
  3329.     }
  3330.     if (ED_IMAGE_ENCODER_EXCEPTION==status)
  3331.     {
  3332.         return;
  3333.     }
  3334.     if (ED_IMAGE_ENCODER_OK==status)
  3335.     {
  3336.         if (t_hook->m_outputimagecontext->m_callbacks.m_completecallback)
  3337.         (*t_hook->m_outputimagecontext->m_callbacks.m_completecallback)(t_hook->m_outputimagecontext,1,t_hook->m_pMWContext);
  3338.         XP_FREE(t_hook);//allocated elsewhere
  3339.     }
  3340. }
  3341.  
  3342.                               
  3343. CONVERT_IMAGERESULT
  3344. FE_ImageDoneCallBack(CONVERT_IMGCONTEXT *p_outputimageContext,int16 p_numoutputs,void *p_pMWContext)
  3345. {
  3346.     MWContext *t_mwcontext=(MWContext *)p_pMWContext;
  3347.     EDT_ImageData* pEdtData = EDT_NewImageData();
  3348.     if( pEdtData )
  3349.     {
  3350.         // We just need to set the URL
  3351.         pEdtData->pSrc = XP_STRDUP(XP_PlatformFileToURL(p_outputimageContext[0].m_filename));
  3352.         //and free memory associated with p_outputimageContext
  3353.         XP_FREE(p_outputimageContext);
  3354.         // Paste the image file:
  3355.         if ( pEdtData->pSrc ) {
  3356.             int bKeepImages;
  3357.             PREF_GetBoolPref("editor.publish_keep_images",&bKeepImages);
  3358.  
  3359.             EDT_InsertImage(t_mwcontext, pEdtData,bKeepImages);
  3360.             XP_FREE(pEdtData->pSrc);
  3361.             pEdtData->pSrc = NULL;
  3362.         }
  3363.     }
  3364.     else
  3365.         return CONVERR_UNKNOWN;
  3366.     EDT_FreeImageData(pEdtData);
  3367.     return CONV_OK;
  3368. }
  3369.  
  3370. //this function takes an array of options and frees their strings 
  3371. void
  3372. free_convert_options(CONVERTOPTION *options,int32 numoptions)
  3373. {
  3374.     if (numoptions)
  3375.         delete [] options;
  3376.     // Don't have to free the options because they are Java strings -- they're garbage collected. (Ooooo!).
  3377. }
  3378.  
  3379.               
  3380. CONVERT_IMAGERESULT
  3381. FE_ImageConvertDialog(CONVERT_IMGCONTEXT *input,CONVERT_IMGCONTEXT *outputarray,CONVERT_IMG_INFO *imginfo,int16 numoutput,CONVERT_IMG_ARRAY imagearray)
  3382. {
  3383.     CEditorResourceDll t_resourcedll;//loads dll if not allready loaded.  this contains code/resources for our dlls
  3384.     //we have 1 built in encoder, JPEG and n # of PLUGIN encoders
  3385.     int32 t_numencoders=EDT_NumberOfEncoders();
  3386.     //we must make a list of available encoders to pass to the convert dialog
  3387.     CONVERTOPTION *t_option=new CONVERTOPTION[1+t_numencoders];
  3388.     if (!t_option||!input||!outputarray||!imginfo||(numoutput!=1))
  3389.     {
  3390.         XP_ASSERT(FALSE);
  3391.         return CONVERR_UNKNOWN;
  3392.     }
  3393.     t_option[0].m_pencodername= "JPEG";
  3394.     t_option[0].m_pfileextention= "JPG";
  3395.     t_option[0].m_phelpstring= "This format is very good for photo style pictures."; // Bug. Make this a string resource.
  3396.     t_option[0].m_builtin=TRUE;
  3397.     for (int32 i=0;i<t_numencoders;i++)//EDT calls indexed by 0 must subtract 1
  3398.     {
  3399.         t_option[i+1].m_pencodername=EDT_GetEncoderName(i);
  3400.         t_option[i+1].m_pfileextention=EDT_GetEncoderFileExtension(i);
  3401.         t_option[i+1].m_phelpstring=EDT_GetEncoderMenuHelp(i);
  3402.         t_option[i+1].m_builtin=FALSE;
  3403.     }
  3404.     IImageConversionDialog *dlg=t_resourcedll.CreateImageConversionDialog(((CWnd *)(input->m_parentwindow))->GetSafeHwnd());
  3405.     if (!dlg)
  3406.     {
  3407.         XP_ASSERT(FALSE);
  3408.         free_convert_options(t_option,1+t_numencoders);
  3409.         return CONVERR_UNKNOWN;
  3410.     }
  3411.     char *t_filename=NULL;
  3412.     if (input->m_stream.m_type==CONVERT_FILE) //we will predict the outcome. we must be prepared for an allready existing file
  3413.     {
  3414.         t_filename=(char *)XP_ALLOC(strlen(input->m_filename)+4);//+4 for the future extention we will add on
  3415.         memcpy(t_filename,input->m_filename,strlen(input->m_filename)+1); //+1 for the null byte
  3416.         if ((strlen(t_filename)>=4)&&(t_filename[strlen(t_filename)-4]=='.'))
  3417.         {
  3418.             t_filename[strlen(t_filename)-4]=0;
  3419.         }//file was xxx.bmp  now= xxx
  3420.     }
  3421.     else if (input->m_stream.m_type==CONVERT_MEMORY)
  3422.     {
  3423.         t_filename=WH_TempName(xpTemporary,"image");
  3424.         t_filename[strlen(t_filename)-4]=0;
  3425.     }
  3426.     if (!t_filename)
  3427.     {
  3428.         XP_ASSERT(FALSE);
  3429.         free_convert_options(t_option,1+t_numencoders);
  3430.         return CONVERR_UNKNOWN;
  3431.     }
  3432.  
  3433.     dlg->setOutputFileName1(t_filename);
  3434.     dlg->setOutputImageType1(0);//JPEG= default
  3435.     dlg->setConvertOptions(t_option,t_numencoders+1);
  3436.     CWFEWrapper t_wfe;
  3437.     if (input->m_pMWContext)
  3438.     {
  3439.         t_wfe.setMWContext((MWContext *)input->m_pMWContext);
  3440.         dlg->setWFEInterface(&t_wfe);
  3441.     }
  3442.     free(t_filename);
  3443.     if (IDOK==dlg->DoModal())
  3444.     {
  3445.         //must check return value of plugin start encode!
  3446.         int32 t_type=dlg->getOutputImageType1();
  3447.         XP_ASSERT(t_type<1+t_numencoders);
  3448.         CString t_string(dlg->getOutputFileName1());
  3449.         strcpy(outputarray[0].m_filename,t_string);
  3450.         
  3451.         outputarray[0].m_stream.m_type=CONVERT_FILE;
  3452.         //call plugin
  3453.         if (!t_option[t_type].m_builtin)
  3454.         {//we have a plug in
  3455.             if (EDT_GetEncoderNeedsQuantizedSource(t_type-1))//-1 for built in JPEG
  3456.             {//quantize it!
  3457.                 /*convert API*/
  3458.                 CONVERT_IMAGERESULT t_result;
  3459.                 t_result=convert_quantize_pixels((unsigned char **)imagearray,imginfo->m_image_width,imginfo->m_image_height,EDTMAXCOLORVALUE);
  3460.                 if (t_result!=CONV_OK)
  3461.                 {
  3462.                     free_convert_options(t_option,1+t_numencoders);
  3463.                     return t_result;
  3464.                 }
  3465.             }
  3466.             PluginHookStruct *t_hook=(PluginHookStruct *)XP_ALLOC(sizeof(PluginHookStruct));
  3467.             t_hook->m_outputimagecontext=outputarray;
  3468.             t_hook->m_pMWContext=(MWContext *)input->m_pMWContext;
  3469.             //do NOT open file for encoder.
  3470.             if (!EDT_StartEncoder((MWContext *)input->m_pMWContext,t_type-1,imginfo->m_image_width,
  3471.                 imginfo->m_image_height,(char**)imagearray,outputarray[0].m_filename,FE_ImageConvertPluginCallback,(void *)t_hook))
  3472.             {
  3473.                 free_convert_options(t_option,1+t_numencoders);
  3474.                 return CONVERR_UNKNOWN;
  3475.             }
  3476.             outputarray[0].m_imagetype=conv_plugin;
  3477.         }
  3478.         else
  3479.         {
  3480.             IJPEGOptionsDlg *t_jpgdlg=t_resourcedll.CreateJpegDialog(((CWnd *)input->m_parentwindow)->GetSafeHwnd());
  3481.             t_jpgdlg->setOutputImageQuality(DEFAULT_IMG_CONVERT_QUALITY);
  3482.             int t_result=t_jpgdlg->DoModal();
  3483.             outputarray[0].m_quality=(int16)t_jpgdlg->getOutputImageQuality();
  3484.             delete t_jpgdlg;
  3485.             if (IDOK!=t_result)
  3486.             {
  3487.                 free_convert_options(t_option,1+t_numencoders);
  3488.                 return CONV_CANCEL;
  3489.             }
  3490.             outputarray[0].m_imagetype=conv_jpeg;
  3491.             //must be open for rest of converter to work
  3492.         }
  3493.         free_convert_options(t_option,1+t_numencoders);
  3494.         return CONV_OK;
  3495.     }
  3496.     free_convert_options(t_option,1+t_numencoders);
  3497.     return CONV_CANCEL;
  3498. }
  3499.  
  3500. void FE_ImageConvertDisplayBuffer(void *)
  3501. {
  3502.  
  3503. }
  3504.  
  3505.  
  3506. #endif //_IMAGE_CONVERT
  3507.  
  3508.  
  3509. int 
  3510. CNetscapeEditView::findDifference(const char *p_str1,const char *p_str2,MWContext *p_pmwcontext) //-1==no difference
  3511. {
  3512.     if (!p_pmwcontext)
  3513.         return -1;
  3514.     char *t_pchar1=(char *)p_str1;
  3515.     char *t_pchar2=(char *)p_str2;
  3516.     char *t_fut1;
  3517.     char *t_fut2;
  3518.     INTL_CharSetInfo csi = LO_GetDocumentCharacterSetInfo(p_pmwcontext);
  3519.     int16 win_csid = INTL_GetCSIWinCSID(csi);
  3520.     for (;*t_pchar1&&*t_pchar2;)
  3521.     {
  3522.         t_fut1=INTL_NextChar(win_csid, t_pchar1);
  3523.         t_fut2=INTL_NextChar(win_csid, t_pchar2);
  3524.         if (memcmp(t_pchar1,t_pchar2,t_fut1-t_pchar1))
  3525.             return t_pchar1-p_str1; 
  3526.         t_pchar1=t_fut1; 
  3527.         t_pchar2=t_fut2; 
  3528.     }
  3529.     if (!*t_pchar1&&!*t_pchar2)
  3530.         return -1;
  3531.     return t_pchar1-p_str1;
  3532. }
  3533.  
  3534. // For automated testing by QA only
  3535. void CNetscapeEditView::OnSelectNextNonTextObject()
  3536. {
  3537.     EDT_SelectNextNonTextObject(GET_MWCONTEXT);
  3538. }
  3539. #endif // EDITOR
  3540.