home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / winfe / edview2.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  149.4 KB  |  4,593 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. // edview2.cpp : 2nd implementation file of the CNetscapeEditView class
  20. //
  21. //
  22.  
  23. #include "stdafx.h"
  24. #ifdef EDITOR
  25. #include "edview.h"
  26. #include "edprops.h"
  27. #include "edt.h"
  28. #include "mainfrm.h"
  29. #include "edframe.h"
  30. #include "edres2.h"
  31. #include "property.h"
  32. #include "edttypes.h"
  33. #include "edtable.h"
  34. #include "prefapi.h"
  35. #include "genframe.h"
  36. #include "intl_csi.h"
  37. #include "abdefn.h"
  38. #include "spellcli.h"
  39.  
  40.  
  41. #ifdef _IME_COMPOSITION
  42. #define CLEARBIT(A, N)    A&=~N
  43. #define SETBIT(A, N)    A|=N
  44.  
  45.     #ifdef XP_WIN16
  46.         #include "ime16.h"
  47.     #else
  48.         #include "intlwin.h"
  49.     #endif //XP_WIN16 else XP_WIN32
  50. #endif
  51.  
  52.  
  53.  
  54. #ifdef _DEBUG
  55. #undef THIS_FILE
  56. static char BASED_CODE THIS_FILE[] = __FILE__;
  57. #endif
  58.  
  59. #ifdef XP_WIN32
  60. #include "shlobj.h"
  61. #endif
  62.  
  63. #ifdef _IME_COMPOSITION
  64. #define CLEARBIT(A, N)    A&=~N
  65. #define SETBIT(A, N)    A|=N
  66. #endif
  67.  
  68. extern char *EDT_NEW_DOC_NAME;
  69.  
  70. // editor plugin info. this is the structure of the array elements stored in m_pPluginInfo.
  71. typedef struct _PluginInfo
  72. {
  73.     uint32  CategoryId;
  74.     uint32  PluginId;
  75. }   PluginInfo;
  76.  
  77. // implemented in edframe.cpp.I changed this to be WFE_FindMenu in winproto.h SP 4/3/97
  78. //int FindMenu(CMenu *pMenu, CString menuItemName);
  79.  
  80. // Global align toolbar 
  81. CDropdownToolbar *pTB = NULL;
  82.  
  83. // Be sure no other timer uses this ID!
  84. #define FEED_IMAGE_LOAD_PAUSE 10
  85.  
  86. // We do this alot
  87. #define GET_MWCONTEXT  (GetContext() == NULL ? NULL : GetContext()->GetContext())
  88.  
  89. // This is TRUE only if we have a context and are not an Editor or 
  90. //   we are an editor that has a good buffer and is not blocked 
  91. // THIS MUST BE THE SAME AS IN EDVIEW2.CPP
  92. #define CAN_INTERACT  (GetContext() != NULL && GetContext()->GetContext() != NULL \
  93.                        && !GetContext()->GetContext()->waitingMode \
  94.                        && (!EDT_IS_EDITOR(GetContext()->GetContext()) \
  95.                            || (EDT_HaveEditBuffer(GetContext()->GetContext()) && !EDT_IsBlocked(GetContext()->GetContext()))))
  96.  
  97. extern BOOL wfe_bUseLastFrameLocation;
  98.  
  99. // Helper for graying out unselecting before insert objects
  100. BOOL NonLinkObjectIsSelected(MWContext *pMWContext)
  101. {
  102.     ASSERT(pMWContext );
  103.     ED_ElementType type = EDT_GetCurrentElementType(pMWContext);
  104.     return ( type == ED_ELEMENT_HRULE ||
  105.              type == ED_ELEMENT_UNKNOWN_TAG ||
  106.              type == ED_ELEMENT_TARGET ||
  107.              type == ED_ELEMENT_TABLE);
  108.     // Note: This is always followed by EDT_ClearSelection(),
  109.     //  so we can ignore Table/Cell selection
  110. }
  111.  
  112. /////////////////////////////////////////////////////////////////////////
  113. // Array used to map TagIDs onto listbox indexes for Paragraph styles
  114. //
  115. // These must match order of items in editor.rc2 -- menu and listbox text
  116. TagType FEED_nParagraphTags[] =
  117. {
  118.     P_NSDT,
  119.     P_HEADER_1,
  120.     P_HEADER_2,
  121.     P_HEADER_3,
  122.     P_HEADER_4,
  123.     P_HEADER_5,
  124.     P_HEADER_6,
  125.     P_ADDRESS,
  126.     P_PREFORMAT,
  127.     P_LIST_ITEM,
  128.     P_DESC_TITLE,
  129.     P_DESC_TEXT,
  130.     P_UNKNOWN       // This must be last - we use it for end-of-loop
  131. };
  132.  
  133.  
  134. void CNetscapeEditView::OnInsertNonbreakingSpace(){
  135.     EDT_InsertNonbreakingSpace( GET_MWCONTEXT );
  136. }
  137.  
  138. void CNetscapeEditView::OnInsertTarget()
  139. {
  140.     MWContext * pMWContext = GET_MWCONTEXT;
  141.     if( pMWContext ){
  142.         // Edit name of existing target if it is selected object
  143.         if( ED_ELEMENT_TARGET == EDT_GetCurrentElementType(pMWContext) ) {
  144.             OnTargetProperties();
  145.             return;
  146.         }
  147.         // Unselect so we insert after after the object
  148.         if( NonLinkObjectIsSelected(pMWContext) )
  149.             EDT_ClearSelection(pMWContext);
  150.  
  151.         // Default for 3rd param will force inserting new target
  152.         CTargetDlg dlg(this, GET_MWCONTEXT);
  153.         dlg.DoModal();
  154.     }
  155. }
  156.  
  157. void CNetscapeEditView::OnTargetProperties()
  158. {
  159.     char * pName = NULL;
  160.     if( ED_ELEMENT_TARGET == EDT_GetCurrentElementType(GET_MWCONTEXT) ) {
  161.         pName = EDT_GetTargetData(GET_MWCONTEXT);
  162.     }
  163.  
  164.     CTargetDlg dlg(this, GET_MWCONTEXT, pName);
  165.     dlg.DoModal();
  166.  
  167.     if(pName) XP_FREE(pName);
  168. }
  169.  
  170. void CNetscapeEditView::OnUpdateTargetProperties(CCmdUI* pCmdUI)
  171. {
  172.     // Must be on an existing link:
  173.     pCmdUI->Enable( CAN_INTERACT && 
  174.                     ED_ELEMENT_TARGET == EDT_GetCurrentElementType(GET_MWCONTEXT) );
  175. }
  176.  
  177. void CNetscapeEditView::OnInsertTag()
  178. {
  179.     MWContext * pMWContext = GET_MWCONTEXT;
  180.     if( pMWContext ){
  181.         // Edit properties of existing tag if it is the selected object
  182.         if( ED_ELEMENT_UNKNOWN_TAG == EDT_GetCurrentElementType(pMWContext) ) {
  183.             OnTagProperties();
  184.             return;
  185.         }
  186.         // Unselect so we insert after after the object
  187.         if( NonLinkObjectIsSelected(pMWContext) )
  188.             EDT_ClearSelection(pMWContext);
  189.  
  190.         // NULL default for 3rd param will force inserting new tag
  191.         CTagDlg dlg(this, pMWContext);
  192.         dlg.DoModal();
  193.     }
  194. }
  195.  
  196. void CNetscapeEditView::OnTagProperties()
  197. {
  198.     char * pTag = NULL;
  199.     if( ED_ELEMENT_UNKNOWN_TAG == EDT_GetCurrentElementType(GET_MWCONTEXT) ) {
  200.         pTag = EDT_GetUnknownTagData(GET_MWCONTEXT);
  201.     }
  202.  
  203.     CTagDlg dlg(this, GET_MWCONTEXT, pTag);
  204.     dlg.DoModal();
  205.  
  206.     if(pTag) XP_FREE(pTag);
  207. }
  208.  
  209. void CNetscapeEditView::OnUpdateTagProperties(CCmdUI* pCmdUI)
  210. {
  211.     pCmdUI->Enable( CAN_INTERACT && 
  212.                     ED_ELEMENT_UNKNOWN_TAG == EDT_GetCurrentElementType(GET_MWCONTEXT) );
  213. }
  214. ///////////////////////////////////////////////////////////////
  215. // Edit menu
  216. // Find is shared with Navigator - uses common dialog
  217. // Replase only seems to be called from outside (by the bookmark window?)
  218. //   via a registered message
  219. //
  220. void CNetscapeEditView::OnEditFindReplace()
  221. {
  222.     // TODO: something like:  CMainFrame::OnFindReplace();
  223. }
  224.  
  225. ///////////////////////////////////////////////////////////////
  226. // Insert menu
  227.  
  228. ///////////////////////////////////////////////////////////////
  229. // Format menu
  230.  
  231. void CNetscapeEditView::OnFormatParagraph( UINT nID )
  232. {
  233.       MWContext *pMWContext = GET_MWCONTEXT;
  234.     if( pMWContext ){
  235.         // Should be current, but lets get style to be sure
  236.         UINT nParagraphFormat = (UINT)EDT_GetParagraphFormatting( pMWContext );
  237.         UINT nNewParagraphFormat = CASTUINT(nID-ID_FORMAT_PARAGRAPH_BASE);
  238.         EDT_MorphContainer( pMWContext, nNewParagraphFormat);
  239.         if( nNewParagraphFormat == P_DESC_TEXT || nNewParagraphFormat == P_DESC_TITLE ){
  240.             // We should have a description list
  241.             EDT_MorphContainer(pMWContext, P_DESC_LIST);
  242.         }
  243.     }
  244. }
  245.  
  246. void CNetscapeEditView::OnFontSize_2()
  247. {
  248.     OnFontSize(ID_FORMAT_FONTSIZE_BASE);
  249. }
  250. void CNetscapeEditView::OnFontSize_1()
  251. {
  252.     OnFontSize(ID_FORMAT_FONTSIZE_BASE+1);
  253. }
  254. void CNetscapeEditView::OnFontSize0()
  255. {
  256.     OnFontSize(ID_FORMAT_FONTSIZE_BASE+2);
  257. }
  258. void CNetscapeEditView::OnFontSize1()
  259. {
  260.     OnFontSize(ID_FORMAT_FONTSIZE_BASE+3);
  261. }
  262. void CNetscapeEditView::OnFontSize2()
  263. {
  264.     OnFontSize(ID_FORMAT_FONTSIZE_BASE+4);
  265. }
  266. void CNetscapeEditView::OnFontSize3()
  267. {
  268.     OnFontSize(ID_FORMAT_FONTSIZE_BASE+5);
  269. }
  270. void CNetscapeEditView::OnFontSize4()
  271. {
  272.     OnFontSize(ID_FORMAT_FONTSIZE_BASE+6);
  273. }
  274.  
  275. void CNetscapeEditView::SetPointSize(int iPointSize)
  276. {
  277.     // If Selected, we can't be sure of multible attributes, so set it
  278.     if ( iPointSize > 0  && iPointSize != m_EditState.iFontSize ||
  279.          EDT_IsSelected(GET_MWCONTEXT) )
  280.     {
  281.         EDT_SetFontPointSize(GET_MWCONTEXT, iPointSize);
  282.            // Triggers OnUpdate... to get fontsize set and update combobox
  283.         m_EditState.bFontSizeMaybeChanged = TRUE;
  284.     }
  285. }
  286.  
  287. void CNetscapeEditView::OnPointSize8()
  288. {
  289.     SetPointSize(8);
  290. }
  291. void CNetscapeEditView::OnPointSize9()
  292. {
  293.     SetPointSize(9);
  294. }
  295. void CNetscapeEditView::OnPointSize10()
  296. {
  297.     SetPointSize(10);
  298. }
  299. void CNetscapeEditView::OnPointSize11()
  300. {
  301.     SetPointSize(11);
  302. }
  303.  
  304. void CNetscapeEditView::OnPointSize12()
  305. {
  306.     SetPointSize(12);
  307. }
  308.  
  309. void CNetscapeEditView::OnPointSize14()
  310. {
  311.     SetPointSize(14);
  312. }
  313.  
  314. void CNetscapeEditView::OnPointSize16()
  315. {
  316.     SetPointSize(16);
  317. }
  318.  
  319. void CNetscapeEditView::OnPointSize18()
  320. {
  321.     SetPointSize(18);
  322. }
  323.  
  324. void CNetscapeEditView::OnPointSize20()
  325. {
  326.     SetPointSize(20);
  327. }
  328.  
  329. void CNetscapeEditView::OnPointSize22()
  330. {
  331.     SetPointSize(22);
  332. }
  333.  
  334. void CNetscapeEditView::OnPointSize24()
  335. {
  336.     SetPointSize(24);
  337. }
  338.  
  339. void CNetscapeEditView::OnPointSize28()
  340. {
  341.     SetPointSize(28);
  342. }
  343.  
  344. void CNetscapeEditView::OnPointSize36()
  345. {
  346.     SetPointSize(36);
  347. }
  348.  
  349. void CNetscapeEditView::OnPointSize48()
  350. {
  351.     SetPointSize(48);
  352. }
  353.  
  354. void CNetscapeEditView::OnPointSize72()
  355. {
  356.     SetPointSize(72);
  357. }
  358.  
  359. void CNetscapeEditView::OnCharacterNoTextStyles()
  360. {
  361.     if ( GET_MWCONTEXT ) {
  362.         // Clear all styles EXCEPT HREF
  363.         EDT_CharacterData *pData = EDT_GetCharacterData(GET_MWCONTEXT);
  364.         if( pData ){
  365.             // Set all bits except href's
  366.             pData->mask = ~TF_HREF;
  367.             pData->values = TF_NONE;
  368.             EDT_SetCharacterData(GET_MWCONTEXT, pData);
  369.             EDT_FreeCharacterData(pData);
  370.             return;
  371.         }
  372.     }
  373. }
  374.  
  375. void CNetscapeEditView::OnCharacterNone()
  376. {
  377.     XP_Bool prefBool;
  378.     PREF_GetBoolPref("editor.hints.removelinks",&prefBool);
  379.     // Warn user if any links are included 
  380.     if ( EDT_SelectionContainsLink(GET_MWCONTEXT) &&
  381.          prefBool ){
  382.         // Show a "Hint" dialog to warn user that
  383.         //   default behavior is to remove links
  384.         //   Use "Yes/No" mode (last param=TRUE)
  385.         //   to clear all styles but leave links alone
  386.         
  387.         CEditHintDlg dlg(this, IDS_UNLINK_WARNING,
  388.                          IDS_CLEAR_CHAR_STYLES_CAPTION, TRUE);
  389.  
  390.         UINT nRetVal = dlg.DoModal();
  391.         if ( dlg.m_bDontShowAgain ) {
  392.             // Suppress showing this again in futures
  393.             PREF_SetBoolPref("editor.hints.removelinks",FALSE);
  394.         }
  395.         if( nRetVal != IDOK ){
  396.             OnCharacterNoTextStyles();
  397.             return;
  398.         }
  399.     }
  400.     EDT_FormatCharacter(GET_MWCONTEXT, TF_NONE);
  401. }
  402.  
  403. void CNetscapeEditView::OnCharacterFixedWidth()
  404. {
  405.     // Set fixed width as a character attribute
  406.     // Note: This acts like a toggle, unlike "Fixed Width" from Font Menu or toolbar
  407.     EDT_FormatCharacter(GET_MWCONTEXT, TF_FIXED);
  408. }
  409.  
  410. void CNetscapeEditView::OnCharacterBold()
  411. {
  412.     EDT_FormatCharacter(GET_MWCONTEXT, TF_BOLD);
  413. }
  414.  
  415. void CNetscapeEditView::OnCharacterItalic()
  416. {
  417.     EDT_FormatCharacter(GET_MWCONTEXT, TF_ITALIC);
  418. }
  419.  
  420. void CNetscapeEditView::OnCharacterNoBreaks()
  421. {
  422.     EDT_FormatCharacter(GET_MWCONTEXT, TF_NOBREAK);
  423. }
  424.  
  425. void CNetscapeEditView::OnCharacterUnderline()
  426. {
  427.     EDT_FormatCharacter(GET_MWCONTEXT, TF_UNDERLINE);
  428. }
  429.  
  430. void CNetscapeEditView::OnCharacterSuper()
  431. {
  432.     EDT_FormatCharacter(GET_MWCONTEXT, TF_SUPER);
  433. }
  434.  
  435. void CNetscapeEditView::OnCharacterSub()
  436. {
  437.     EDT_FormatCharacter(GET_MWCONTEXT, TF_SUB);
  438. }
  439.  
  440. void CNetscapeEditView::OnCharacterStrikeout()
  441. {
  442.     EDT_FormatCharacter(GET_MWCONTEXT, TF_STRIKEOUT);
  443. }
  444.  
  445. void CNetscapeEditView::OnCharacterBlink()
  446. {
  447.     EDT_FormatCharacter(GET_MWCONTEXT, TF_BLINK);
  448. }
  449.  
  450. // Local helper used to get character style state
  451. void SetCharacterCheck(MWContext * pMWContext, CCmdUI* pCmdUI, CComboToolBar* pToolbar, ED_TextFormat tf )
  452. {
  453.     EDT_CharacterData * pData = EDT_GetCharacterData(pMWContext);
  454.     int iCheck = 0;
  455.     if( pData) {
  456.         if( pData->mask & tf ) {
  457.             iCheck = (pData->values & tf ) ? 1 : 0;
  458.         } else if( pToolbar && pToolbar->m_pInfo ) {
  459.             iCheck = 2; // Style is indeterminate
  460.         } else {
  461.             // indeterminate style does not show up in menu - looks checked
  462.             iCheck = 0; // Style is indeterminate
  463.         }
  464.         EDT_FreeCharacterData(pData);
  465.     }
  466.  
  467.     if ( pCmdUI->m_pMenu )              // Always change menu items
  468.         pCmdUI->SetCheck( iCheck );
  469.     else if ( pToolbar && pToolbar->m_pInfo ) {
  470.         pToolbar->SetCheck( pCmdUI->m_nID, iCheck );
  471.     }
  472. }
  473.  
  474. void SetCharacterCheck(MWContext * pMWContext, CCmdUI* pCmdUI, CNSToolbar2* pToolbar, ED_TextFormat tf )
  475. {
  476.     EDT_CharacterData * pData = EDT_GetCharacterData(pMWContext);
  477.     int iCheck = 0;
  478.     if( pData) {
  479.         if( pData->mask & tf ) {
  480.             iCheck = (pData->values & tf ) ? 1 : 0;
  481.         } else if( pToolbar ) {
  482.             iCheck = 2; // Style is indeterminate
  483.         } else {
  484.             // indeterminate style does not show up in menu - looks checked
  485.             iCheck = 0; // Style is indeterminate
  486.         }
  487.         EDT_FreeCharacterData(pData);
  488.     }
  489.  
  490.     if ( pCmdUI->m_pMenu )              // Always change menu items
  491.         pCmdUI->SetCheck( iCheck );
  492.     else if ( pToolbar ) {
  493.         pCmdUI->SetCheck( iCheck );
  494.     }
  495. }
  496.  
  497. void CNetscapeEditView::OnUpdateCharacterBold(CCmdUI* pCmdUI)
  498. {
  499.     CEditToolBarController * pController = 
  500.         (CEditToolBarController *)GetParentFrame()->SendMessage(WM_TOOLCONTROLLER);
  501.     if (pController) {
  502.         SetCharacterCheck(GET_MWCONTEXT, pCmdUI, pController->GetCNSToolbar(), TF_BOLD);
  503.         pCmdUI->Enable( EDT_CanSetCharacterAttribute(GET_MWCONTEXT) );
  504.     }
  505. }
  506.  
  507.  
  508. void CNetscapeEditView::OnUpdateCharacterItalic(CCmdUI* pCmdUI)
  509. {
  510.     CEditToolBarController * pController = 
  511.         (CEditToolBarController *)GetParentFrame()->SendMessage(WM_TOOLCONTROLLER);
  512.     if (pController) {
  513.         SetCharacterCheck(GET_MWCONTEXT, pCmdUI, pController->GetCNSToolbar(), TF_ITALIC);
  514.         pCmdUI->Enable( EDT_CanSetCharacterAttribute(GET_MWCONTEXT) );
  515.     }
  516. }
  517.  
  518.  
  519. void CNetscapeEditView::OnUpdateCharacterNoBreaks(CCmdUI* pCmdUI)
  520. {
  521.     CEditToolBarController * pController = 
  522.         (CEditToolBarController *)GetParentFrame()->SendMessage(WM_TOOLCONTROLLER);
  523.     if (pController) {
  524.         SetCharacterCheck(GET_MWCONTEXT, pCmdUI, pController->GetCharacterBar(), TF_NOBREAK);
  525.         pCmdUI->Enable( EDT_CanSetCharacterAttribute(GET_MWCONTEXT) );
  526.     }
  527. }
  528.  
  529. void CNetscapeEditView::OnUpdateCharacterUnderline(CCmdUI* pCmdUI)
  530. {
  531.     CEditToolBarController * pController = 
  532.         (CEditToolBarController *)GetParentFrame()->SendMessage(WM_TOOLCONTROLLER);
  533.     if (pController) {
  534.         SetCharacterCheck(GET_MWCONTEXT, pCmdUI, pController->GetCNSToolbar(), TF_UNDERLINE);
  535.  
  536.         pCmdUI->Enable( EDT_CanSetCharacterAttribute(GET_MWCONTEXT) );
  537.     }
  538. }
  539.  
  540.  
  541. void CNetscapeEditView::OnUpdateCharacterSuper(CCmdUI* pCmdUI)
  542. {
  543.     CEditToolBarController * pController = 
  544.         (CEditToolBarController *)GetParentFrame()->SendMessage(WM_TOOLCONTROLLER);
  545.     if (pController) {
  546.         SetCharacterCheck(GET_MWCONTEXT, pCmdUI, pController->GetCharacterBar(), TF_SUPER);
  547.         pCmdUI->Enable( EDT_CanSetCharacterAttribute(GET_MWCONTEXT) );
  548.     }
  549. }
  550.  
  551.  
  552. void CNetscapeEditView::OnUpdateCharacterSub(CCmdUI* pCmdUI)
  553. {
  554.     CEditToolBarController * pController = 
  555.         (CEditToolBarController *)GetParentFrame()->SendMessage(WM_TOOLCONTROLLER);
  556.     if (pController) {
  557.         SetCharacterCheck(GET_MWCONTEXT, pCmdUI, pController->GetCharacterBar(), TF_SUB);
  558.         pCmdUI->Enable( EDT_CanSetCharacterAttribute(GET_MWCONTEXT) );
  559.     }
  560. }
  561.  
  562.  
  563. void CNetscapeEditView::OnUpdateCharacterStrikeout(CCmdUI* pCmdUI)
  564. {
  565.     CEditToolBarController * pController = 
  566.         (CEditToolBarController *)GetParentFrame()->SendMessage(WM_TOOLCONTROLLER);
  567.     if (pController) {
  568.         SetCharacterCheck(GET_MWCONTEXT, pCmdUI, pController->GetCharacterBar(), TF_STRIKEOUT);
  569.         pCmdUI->Enable( EDT_CanSetCharacterAttribute(GET_MWCONTEXT) );
  570.     }
  571. }
  572.  
  573.  
  574. void CNetscapeEditView::OnUpdateCharacterBlink(CCmdUI* pCmdUI)
  575. {
  576.     CEditToolBarController * pController = 
  577.         (CEditToolBarController *)GetParentFrame()->SendMessage(WM_TOOLCONTROLLER);
  578.     if (pController) {
  579.         SetCharacterCheck(GET_MWCONTEXT, pCmdUI, pController->GetCharacterBar(), TF_BLINK);
  580.         pCmdUI->Enable( EDT_CanSetCharacterAttribute(GET_MWCONTEXT) );
  581.     }
  582. }
  583.  
  584. ////////////////////////////////////////////////////////////////////////////////
  585. void CNetscapeEditView::OnSetFocusParagraphStyle()
  586. {
  587.     CEditToolBarController * pController = 
  588.         (CEditToolBarController *)GetParentFrame()->SendMessage(WM_TOOLCONTROLLER);
  589.     if (pController) {
  590.         pController->GetParagraphCombo()->SetFocus();
  591.         pController->GetParagraphCombo()->ShowDropDown();
  592.     }
  593. }
  594.  
  595. void CNetscapeEditView::OnSetFocusFontFace()
  596. {
  597.     CEditToolBarController * pController = 
  598.         (CEditToolBarController *)GetParentFrame()->SendMessage(WM_TOOLCONTROLLER);
  599.     if (pController) {
  600.         pController->GetFontFaceCombo()->SetFocus();
  601.         pController->GetFontFaceCombo()->ShowDropDown();
  602.     }
  603. }
  604.  
  605. void CNetscapeEditView::OnSetFocusFontSize()
  606. {
  607.     CEditToolBarController * pController = 
  608.         (CEditToolBarController *)GetParentFrame()->SendMessage(WM_TOOLCONTROLLER);
  609.     if (pController) {
  610.         pController->GetFontSizeCombo()->SetFocus();
  611.         pController->GetFontSizeCombo()->ShowDropDown();
  612.     }
  613. }
  614.  
  615. static BOOL bBusy = FALSE;
  616.  
  617. void CNetscapeEditView::OnGetFontColor()
  618. {
  619.     // Prevent recursion
  620.     if( bBusy ){
  621.         return;
  622.     }
  623.     bBusy = TRUE;
  624.  
  625.     CEditToolBarController * pController = 
  626.         (CEditToolBarController *)GetParentFrame()->SendMessage(WM_TOOLCONTROLLER);
  627.     if (pController) {
  628.         pController->GetFontColorCombo()->SendMessage(WM_LBUTTONUP, 0,0);// ShowDropDown(FALSE);
  629.         // NEW: Color Combo is only for showing color in toolbar,
  630.         //   popup dialog to get color to set
  631.         MWContext *pMWContext = GET_MWCONTEXT;
  632.         CComboBox * pCombo = pController->GetFontColorCombo();
  633.         if( !pMWContext || !pCombo ){
  634.             return;
  635.         }
  636.         
  637.         // Get the combobox location so we popup new dialog just under it
  638.         RECT rect = {0,0,0,0};
  639.         if( pCombo->IsWindowVisible() ){
  640.             pCombo->GetWindowRect(&rect);
  641.         }
  642.  
  643.         CColorPicker dlg(GET_DLG_PARENT(this), pMWContext, m_EditState.crFontColor, DEFAULT_COLORREF, 0, &rect); 
  644.  
  645.         COLORREF crNew = dlg.GetColor();
  646.         if( crNew != CANCEL_COLORREF ){
  647.             if ( crNew != m_EditState.crFontColor ||
  648.                  EDT_IsSelected(pMWContext) )
  649.             {
  650.                 if( crNew == DEFAULT_COLORREF ){
  651.                     // Set the "Default" color (actually = no color attribute written)
  652.                     EDT_SetFontColor(pMWContext, NULL);
  653.                 } else {            
  654.                     LO_Color LoColor;
  655.                     WFE_SetLO_Color(crNew, &LoColor);
  656.                     EDT_SetFontColor(pMWContext, &LoColor);
  657.                 }
  658.                 // Trigger update of color in combo display
  659.                 m_EditState.bFontColorMaybeChanged = TRUE;
  660.             }
  661.         }
  662.         // Return focus to the view
  663.         SetFocus();
  664.     }
  665.     bBusy = FALSE;
  666. }
  667.  
  668. ////////////////////////////////////////////////////////////////////////////////
  669.  
  670. // User presses Esc key while in any combobox - return focus to main view
  671. void CNetscapeEditView::OnCancelComboBox()
  672. {
  673.     // Return focus to view
  674.     SetFocus();
  675. }
  676.  
  677. void CNetscapeEditView::OnSelendokParagraphCombo()
  678. {
  679.     // TODO: ADD CODE TO TEST IF ALLOWED TO CHANGE STYLE!
  680.  
  681.     // Get index to selected item in Paragraph styles list
  682.     CEditToolBarController * pController = 
  683.         (CEditToolBarController *)GetParentFrame()->SendMessage(WM_TOOLCONTROLLER);
  684.     if (pController) {
  685.         UINT    nSelected = pController->GetParagraphCombo()->GetCurSel();
  686.  
  687.         if ( nSelected >= 0 && 
  688.             m_EditState.nParagraphFormat != FEED_nParagraphTags[nSelected] )
  689.         {
  690.             OnFormatParagraph(CASTUINT(FEED_nParagraphTags[nSelected]+ID_FORMAT_PARAGRAPH_BASE));
  691.             m_EditState.bParaFormatMaybeChanged = TRUE;
  692.         }
  693.     
  694.         // Return focus to view
  695.         SetFocus();
  696.     }
  697. }
  698.  
  699.  
  700. // No paragraph buttons on toolbar -- just in menu
  701. void CNetscapeEditView::OnUpdateParagraphMenu(CCmdUI* pCmdUI)
  702. {   
  703.     TagType nParagraphFormat = EDT_GetParagraphFormatting( GET_MWCONTEXT );
  704.         
  705.     pCmdUI->SetCheck(nParagraphFormat == (TagType)(pCmdUI->m_nID - ID_FORMAT_PARAGRAPH_BASE));
  706.     pCmdUI->Enable(CAN_INTERACT  && !EDT_IsJavaScript(GET_MWCONTEXT));
  707. }
  708.  
  709.  
  710. void CNetscapeEditView::OnUpdateParagraphComboBox(CCmdUI* pCmdUI)
  711. {
  712.     if ( m_EditState.bParaFormatMaybeChanged && 
  713.          GetFocus() == this )
  714.     {
  715.         TagType nParagraphFormat = EDT_GetParagraphFormatting( GET_MWCONTEXT );
  716.  
  717.         if ( m_EditState.nParagraphFormat != nParagraphFormat )
  718.         {
  719.             CEditToolBarController * pController = 
  720.                 (CEditToolBarController *)GetParentFrame()->SendMessage(WM_TOOLCONTROLLER);
  721.             if (pController) {
  722.                 if ( nParagraphFormat == P_UNKNOWN ) 
  723.                     pController->GetParagraphCombo()->SetCurSel(-1);
  724.                 else
  725.                     for ( int i = 0; FEED_nParagraphTags[i] != P_UNKNOWN; i++ )
  726.                     {
  727.                         if ( FEED_nParagraphTags[i] == nParagraphFormat )
  728.                         {    
  729.                             pController->GetParagraphCombo()->SetCurSel(i);
  730.                             break;
  731.                         }
  732.                     }
  733.             
  734.                 // Note that we save state only for Toolbar
  735.                 m_EditState.nParagraphFormat = nParagraphFormat;
  736.             }
  737.         }
  738.         m_EditState.bParaFormatMaybeChanged = FALSE;
  739.     }
  740.     pCmdUI->Enable( CAN_INTERACT ); // Should we do this: !EDT_IsJavaScript(GET_MWCONTEXT) );
  741. }
  742.  
  743. /////////////////////////////////////////////////////////////////////////
  744. // Font Face controls
  745.  
  746. void CNetscapeEditView::OnUpdateFontFaceComboBox(CCmdUI* pCmdUI)
  747. {
  748.     if ( m_EditState.bFontFaceMaybeChanged && 
  749.          GetFocus() == this )
  750.     {
  751.         MWContext *pMWContext = GET_MWCONTEXT;
  752.         if(pMWContext){
  753.             CEditToolBarController * pController = 
  754.                 (CEditToolBarController *)GetParentFrame()->SendMessage(WM_TOOLCONTROLLER);
  755.             if (pController) {
  756.                 CNSComboBox * pCombo = pController->GetFontFaceCombo();
  757.                 char * pFace = EDT_GetFontFace(pMWContext);
  758.                 int iFontIndex;
  759.                 if( pFace ){
  760.                     iFontIndex = pCombo->FindSelectedOrSetText(pFace);
  761.                 } else {
  762.                     iFontIndex = -1;
  763.                     pCombo->SetCurSel(iFontIndex);
  764.                 }
  765.                 // Note: We always update this before size combox, thus
  766.                 //   we can see if font base size has changed and we are
  767.                 //   changing from FixedWidth to not-FixedWidth or vice versa.
  768.                 //   If we are changing, then we must force update of font size value
  769.                 //     when we are converting relative size to points
  770.                 if( wfe_iFontSizeMode == ED_FONTSIZE_POINTS &&
  771.                     iFontIndex != m_EditState.iFontIndex &&
  772.                     (iFontIndex == 1 || m_EditState.iFontIndex == 1) ){
  773.                     m_EditState.iFontSize = -1;    
  774.                     m_EditState.bFontSizeMaybeChanged = TRUE;
  775.                 }
  776.                 m_EditState.iFontIndex = iFontIndex;
  777.                 m_EditState.bFontFaceMaybeChanged = FALSE;
  778.             }
  779.         }
  780.     }
  781.     pCmdUI->Enable( CAN_INTERACT ); // Should we do this: !EDT_IsJavaScript(GET_MWCONTEXT) );
  782. }
  783.  
  784. void CNetscapeEditView::OnSelendokFontFaceCombo()
  785. {
  786.     CEditToolBarController * pController = 
  787.         (CEditToolBarController *)GetParentFrame()->SendMessage(WM_TOOLCONTROLLER);
  788.     if (pController) {
  789.         int iFontIndex = pController->GetSelectedFontFaceIndex();
  790.         // Process "Other..." to get font from dialog and set it
  791.         if( iFontIndex == INDEX_OTHER ){
  792.             OnSetLocalFontFace();
  793.             return;
  794.         } else {
  795.             // Let cross platform code process font face string from combobox
  796.             EDT_SetFontFace(GET_MWCONTEXT, NULL, 0, 
  797.                             (char*)pController->GetFontFaceCombo()->GetItemData(iFontIndex));
  798.         }
  799.         SetFocus();
  800.     }
  801. }
  802.  
  803. void CNetscapeEditView::OnRemoveFontFace()
  804. {
  805.     // Set font to the "default proportional font",
  806.     //  which effectively removes the tag
  807.     EDT_SetFontFace(GET_MWCONTEXT, NULL, 0, NULL);
  808. }
  809.  
  810. void CNetscapeEditView::OnSetLocalFontFace()
  811. {
  812.     // Popup Window's font face picker dialog
  813.     CFontDialog dlg(NULL, CF_SCREENFONTS | CF_TTONLY, NULL, this);
  814.     if( dlg.DoModal() ){
  815.         CString csNewFont = dlg.GetFaceName();
  816.         // Set the arbitrary font face 
  817.         EDT_SetFontFace(GET_MWCONTEXT, NULL, 0, (char*)LPCSTR(csNewFont));
  818.         // Trigger update of fontname in toolbar combobox
  819.         m_EditState.bFontFaceMaybeChanged = TRUE;
  820.     }
  821. }
  822.  
  823. /////////////////////////////////////////////////////////////////////////
  824. // Font Size controls
  825.  
  826. // Menu only:
  827. void CNetscapeEditView::OnFontSize(UINT nID)
  828. {
  829.     int    iNewFontSize = (int)(nID - ID_FORMAT_FONTSIZE_BASE + 1);
  830.  
  831.     // If Selected, we can't be sure of multible attributes, so always set it
  832.     if ( iNewFontSize != EDT_GetFontSize( GET_MWCONTEXT ) ||
  833.          EDT_IsSelected(GET_MWCONTEXT) )
  834.     {
  835.         // Set the size using relative font scale (1 to 7)
  836.         EDT_SetFontSize( GET_MWCONTEXT, iNewFontSize );
  837.  
  838.         // Triggers OnUpdate... to get fontsize set and update combobox
  839.         m_EditState.bFontSizeMaybeChanged = TRUE;
  840.     }
  841. }
  842.  
  843. // Menu only:
  844. void CNetscapeEditView::OnUpdateFontSizeMenu(CCmdUI* pCmdUI)
  845. {
  846.     int iFontSizeIndex = EDT_GetFontSize( GET_MWCONTEXT ) - 1;
  847.     pCmdUI->SetCheck((UINT)iFontSizeIndex == (pCmdUI->m_nID - ID_FORMAT_FONTSIZE_BASE));
  848.     pCmdUI->Enable(CAN_INTERACT && EDT_CanSetCharacterAttribute(GET_MWCONTEXT));
  849. }
  850.  
  851. void CNetscapeEditView::OnSelendokFontSizeCombo()
  852. {
  853.     MWContext *pMWContext = GET_MWCONTEXT;
  854.     if(!pMWContext){
  855.         return;
  856.     }
  857.     
  858.     // Font size is 1 more than index to selected item
  859.     CEditToolBarController * pController = 
  860.         (CEditToolBarController *)GetParentFrame()->SendMessage(WM_TOOLCONTROLLER);
  861.     if (pController) {
  862.         int iSel = pController->GetFontSizeCombo()->GetCurSel();
  863.         int iNewFontSize =  0;
  864.  
  865.         if( iSel < MAX_FONT_SIZE ){
  866.             iNewFontSize =  iSel + 1;
  867.         } else {
  868.             char pSize[16] = "";
  869.             char *pEnd;
  870.             strcpy(pSize, (char*)pController->GetFontSizeCombo()->GetItemData(iSel));
  871.             int iSize = (int)strtol( pSize, &pEnd, 10 );
  872.             if( *pEnd == '\0' ){
  873.                 iNewFontSize = iSize;
  874.             }
  875.         }
  876.         // If Selected, we can't be sure of multible attributes, so set it
  877.         if ( iNewFontSize > 0  && iNewFontSize != m_EditState.iFontSize ||
  878.              EDT_IsSelected(pMWContext) )
  879.         {
  880.             if( iSel < MAX_FONT_SIZE ){
  881.                 EDT_SetFontSize(pMWContext, iNewFontSize);
  882.             } else {
  883.                 EDT_SetFontPointSize(pMWContext, iNewFontSize);
  884.             }
  885.             // Triggers OnUpdate... to get fontsize set and update combobox
  886.             m_EditState.bFontSizeMaybeChanged = TRUE;
  887.         }
  888.         SetFocus();
  889.     }
  890. }
  891.  
  892. void CNetscapeEditView::OnFontSizeDropDown()
  893. {
  894.     CEditToolBarController * pController = 
  895.         (CEditToolBarController *)GetParentFrame()->SendMessage(WM_TOOLCONTROLLER);
  896.     if (pController) {
  897.         CNSComboBox * pCombo = pController->GetFontSizeCombo();
  898.         int iSel = pCombo->GetCurSel();
  899.         // Refill font sizes in case font basesize changed
  900.         //  (when switching from variable to fixed width font or vice versa)
  901.         // 3rd param = TRUE when using Fixed Width font
  902.         wfe_FillFontSizeCombo(GET_MWCONTEXT, pCombo, (EDT_GetFontFaceIndex(GET_MWCONTEXT) == 1));
  903.         pCombo->SetCurSel(iSel);
  904.         
  905.         // Allow search function, but doesn't make much sense in pure relative mode
  906.         if( wfe_iFontSizeMode != ED_FONTSIZE_RELATIVE ){
  907.             pCombo->InitSearch();
  908.         }
  909.     }
  910. }
  911.  
  912. void CNetscapeEditView::OnUpdateFontSizeComboBox(CCmdUI* pCmdUI)
  913. {
  914.     if ( m_EditState.bFontSizeMaybeChanged &&
  915.          GetFocus() == this )
  916.     {
  917.         MWContext *pMWContext = GET_MWCONTEXT;
  918.         int    iFontSize = 0;
  919.         if( pMWContext ){
  920.             EDT_CharacterData * pData = EDT_GetCharacterData(pMWContext);
  921.             if(pData){
  922.                 iFontSize = pData->iPointSize ? pData->iPointSize : pData->iSize;
  923.                 int iFontIndex = EDT_GetFontFaceIndex(pMWContext);
  924.                 if( iFontSize != m_EditState.iFontSize ||
  925.                     iFontIndex != m_EditState.iFontIndex || 
  926.                     iFontIndex > 1 ){
  927.                     CEditToolBarController * pController = 
  928.                         (CEditToolBarController *)GetParentFrame()->SendMessage(WM_TOOLCONTROLLER);
  929.                     if (pController) {
  930.                         char * pSize = NULL;
  931.                         char pSizeNotInList[16];
  932.                         if( iFontSize > 0 && iFontSize <= MAX_FONT_SIZE ){
  933.                             pController->GetFontSizeCombo()->SetCurSel(iFontSize-1);
  934.                             pSize = wfe_GetFontSizeString(pMWContext, iFontSize, iFontIndex == 1);
  935.                         } else {
  936.                             wsprintf(pSizeNotInList, "%d", iFontSize);
  937.                             pSize = pSizeNotInList;
  938.                         }
  939.                         if(pSize){
  940.                             pController->GetFontSizeCombo()->FindSelectedOrSetText(pSize, MAX_FONT_SIZE);
  941.                         }
  942.                     }
  943.                 }
  944.                 m_EditState.iFontSize = iFontSize;
  945.                 EDT_FreeCharacterData(pData);
  946.            }
  947.            m_EditState.bFontSizeMaybeChanged = FALSE;
  948.         }
  949.         if( pCmdUI ){
  950.             pCmdUI->Enable( EDT_CanSetCharacterAttribute(pMWContext) );
  951.         }
  952.     }
  953. }
  954.  
  955. void CNetscapeEditView::UpdateFontSizeCombo()
  956. {
  957.     // Change current state to force updating the combo
  958.     m_EditState.bFontSizeMaybeChanged = TRUE;
  959.     m_EditState.iFontSize = -2;
  960.     CEditToolBarController * pController = 
  961.         (CEditToolBarController *)GetParentFrame()->SendMessage(WM_TOOLCONTROLLER);
  962.     if (pController) {
  963.         wfe_FillFontSizeCombo(GET_MWCONTEXT, pController->GetFontSizeCombo(), 
  964.                               (EDT_GetFontFaceIndex(GET_MWCONTEXT) == 1));
  965.     }
  966.     OnUpdateFontSizeComboBox(NULL);
  967. }
  968.  
  969. void CNetscapeEditView::OnIncreaseFontSize()
  970. {
  971.     int    iFontSize = EDT_GetFontSize( GET_MWCONTEXT );
  972.     // TODO: MAKE THIS WORK WITH ABSOLUTE POINT SIZE?
  973.     if ( iFontSize < MAX_FONT_SIZE ) // 7
  974.     {
  975.         EDT_SetFontSize( GET_MWCONTEXT, iFontSize + 1 );
  976.         m_EditState.bFontSizeMaybeChanged = TRUE;
  977.     }
  978. }
  979.  
  980. void CNetscapeEditView::OnDecreaseFontSize()
  981. {
  982.     int    iFontSize = EDT_GetFontSize( GET_MWCONTEXT );
  983.     
  984.     // TODO: MAKE THIS WORK WITH ABSOLUTE POINT SIZE?
  985.     if ( iFontSize > 1 )
  986.     {
  987.         EDT_SetFontSize( GET_MWCONTEXT, iFontSize - 1 );
  988.         m_EditState.bFontSizeMaybeChanged = TRUE;
  989.     }
  990. }
  991.  
  992. void CNetscapeEditView::OnUpdateIncreaseFontSize(CCmdUI* pCmdUI)
  993. {
  994.     pCmdUI->Enable( EDT_CanSetCharacterAttribute(GET_MWCONTEXT) );
  995. }
  996.  
  997. void CNetscapeEditView::OnUpdateDecreaseFontSize(CCmdUI* pCmdUI)
  998. {
  999.     pCmdUI->Enable( EDT_CanSetCharacterAttribute(GET_MWCONTEXT) );
  1000. }
  1001.  
  1002. /////////////////////////////////////////////////////////////////////////
  1003. // Font Color controls
  1004.  
  1005.  
  1006. // From the Menu only -- CURRENTLY NO SUBMENU FOR COLOR
  1007. void CNetscapeEditView::OnFontColorMenu(UINT nID)
  1008. {
  1009.     int i = CASTINT(nID - ID_FORMAT_FONTCOLOR_BASE);
  1010.  
  1011.     // Figure out current color at cursor
  1012.     COLORREF crColor = WFE_GetCurrentFontColor(GET_MWCONTEXT);
  1013.  
  1014.     // If Selected, we can't be sure of multible attributes, so set it
  1015.     if ( crColor != wfe_CustomPalette[i] ||
  1016.          EDT_IsSelected(GET_MWCONTEXT) )
  1017.     {
  1018.         // Set the Color 
  1019.         LO_Color FontColor;
  1020.         FontColor.red = GetRValue(wfe_CustomPalette[i]);
  1021.         FontColor.green = GetGValue(wfe_CustomPalette[i]);
  1022.         FontColor.blue = GetBValue(wfe_CustomPalette[i]);
  1023.             
  1024.         EDT_SetFontColor( GET_MWCONTEXT, &FontColor );
  1025.  
  1026.         m_EditState.bFontColorMaybeChanged = TRUE;
  1027.     }
  1028. }
  1029.  
  1030. void CNetscapeEditView::OnUpdateFontColorComboBox(CCmdUI* pCmdUI)
  1031. {
  1032.     CEditToolBarController * pController = 
  1033.                 (CEditToolBarController *)GetParentFrame()->SendMessage(WM_TOOLCONTROLLER);
  1034.     if (pController) {
  1035.         if ( m_EditState.bFontColorMaybeChanged && 
  1036.              GetFocus() == this )
  1037.         {
  1038.             // Figure out current color at cursor
  1039.             COLORREF cr = WFE_GetCurrentFontColor(GET_MWCONTEXT);
  1040.             if( cr != m_EditState.crFontColor ){
  1041.                 // Set color in combobox
  1042.                 pController->GetFontColorCombo()->SetColor(cr);
  1043.                 m_EditState.crFontColor = cr;
  1044.             }
  1045.             m_EditState.bFontColorMaybeChanged = FALSE;
  1046.         }
  1047.     }
  1048.     pCmdUI->Enable( CAN_INTERACT ); // Should we do this: !EDT_IsJavaScript(GET_MWCONTEXT) );
  1049. }
  1050.  
  1051. extern COLORREF crDefaultColor;
  1052.  
  1053. //////////////////////////////////////////////////////////////////
  1054. // Insert Objects and Properties
  1055.  
  1056. void CNetscapeEditView::OnLButtonDblClk(UINT nFlags, CPoint cPoint) 
  1057. // Trap double-click on objects that we want to pop-up property dialogs
  1058. // (Note that we do NOT call CGenericView::OnLButtonDblClk)
  1059. {
  1060.     CView::OnLButtonDblClk(nFlags, cPoint);
  1061.     MWContext *pMWContext = GET_MWCONTEXT;
  1062.     if( !pMWContext )
  1063.         return;
  1064.  
  1065.     XY Point;
  1066.     GetContext()->ResolvePoint(Point, cPoint);
  1067.  
  1068.     BOOL bInLink = !EDT_IsSelected(pMWContext) && EDT_CanSetHREF(pMWContext);
  1069.     if( !bInLink )
  1070.     {
  1071.         switch( EDT_GetCurrentElementType(pMWContext) )
  1072.         {
  1073.             case ED_ELEMENT_IMAGE:
  1074.                 OnImageProperties();
  1075.                 return;
  1076.             case ED_ELEMENT_HRULE:
  1077.                 OnHRuleProperties();
  1078.                 return;
  1079.             case ED_ELEMENT_TARGET:
  1080.                 OnTargetProperties();
  1081.                 return;
  1082.             case ED_ELEMENT_UNKNOWN_TAG:
  1083.                 OnTagProperties();
  1084.                 return;
  1085.             default:
  1086.                 // Check for table hit areas - do table region properties
  1087.                 LO_Element *pTableElement = NULL;
  1088.                 ED_HitType iHit =  EDT_GetTableHitRegion(pMWContext, Point.x, Point.y, &pTableElement, (nFlags & MK_CONTROL));
  1089.                 if( !iHit && pTableElement && pTableElement->type == LO_TABLE )
  1090.                 {
  1091.                     iHit = ED_HIT_SEL_TABLE;
  1092.                 }
  1093.                 int iStartPage = -1;
  1094.                 switch( iHit )
  1095.                 {
  1096.                     case ED_HIT_SEL_TABLE:
  1097.                     case ED_HIT_ADD_ROWS:
  1098.                     case ED_HIT_ADD_COLS:
  1099.                     case ED_HIT_SIZE_TABLE_WIDTH:
  1100.                         // Allow any of 4 corners to select table properties
  1101.                         iStartPage = 0;
  1102.                         break;
  1103.                     case ED_HIT_SEL_ROW:
  1104.                         iStartPage = 1;
  1105.                         break;
  1106.                     case ED_HIT_SEL_COL:
  1107.                         iStartPage = 1;
  1108.                         break;
  1109.                     case ED_HIT_SEL_CELL:
  1110.                     case ED_HIT_SEL_ALL_CELLS:
  1111.                         iStartPage = 1;
  1112.                         break;
  1113.                 }
  1114.                 if( iStartPage >= 0 )
  1115.                 {
  1116.                     // Select the region double-clicked on. 
  1117.                     //  1st FALSE = erase existing table selection, 2nd = don't extend selection
  1118.                     EDT_SelectTableElement(pMWContext, Point.x, Point.y, pTableElement, iHit, FALSE, FALSE);
  1119.                     OnTableProperties(iStartPage);
  1120.                     return;
  1121.                 }
  1122.                 break;
  1123.         }
  1124.     }
  1125.     // This will select a link or word
  1126.     if(GetContext() != NULL && GetContext()->IsDestroyed() == FALSE)
  1127.     {
  1128.         //    Pass it off to the context to handle.
  1129.         GetContext()->OnLButtonDblClkCX(nFlags, cPoint);
  1130.     }
  1131.     // If on a link, popup Link Properties
  1132.     if( bInLink )
  1133.     {
  1134.         OnLinkProperties();
  1135.     }
  1136. }
  1137.  
  1138. // Hook into button up to trigger Update of UI elements after 
  1139. //   dragging a selection
  1140. void CNetscapeEditView::OnLButtonUp(UINT nFlags, CPoint point)
  1141. {
  1142.     CNetscapeView::OnLButtonUp(nFlags, point);
  1143.     SetEditChanged();
  1144. }
  1145.  
  1146. void CNetscapeEditView::OnDisplayTables()
  1147. {
  1148.     EDT_SetDisplayTables(GET_MWCONTEXT, !EDT_GetDisplayTables(GET_MWCONTEXT));
  1149. }
  1150.  
  1151. void CNetscapeEditView::OnUpdateDisplayTables(CCmdUI* pCmdUI)
  1152. {
  1153.     CEditToolBarController * pController = 
  1154.         (CEditToolBarController *)GetParentFrame()->SendMessage(WM_TOOLCONTROLLER);
  1155.     if( pController && pCmdUI->m_pMenu ){
  1156.         pCmdUI->m_pMenu->ModifyMenu(ID_DISPLAY_TABLES, MF_BYCOMMAND | MF_STRING, ID_DISPLAY_TABLES,
  1157.                                     szLoadString(EDT_GetDisplayTables(GET_MWCONTEXT) ?
  1158.                                                  IDS_HIDE_TABLE_BORDERS : IDS_SHOW_TABLE_BORDERS) );
  1159.     }
  1160.     pCmdUI->Enable(CAN_INTERACT);
  1161. }
  1162.  
  1163. void CNetscapeEditView::OnRButtonDown(UINT uFlags, CPoint cpPoint)
  1164. //    Purpose:    Bring up the popup menu.
  1165. //    Arguments:    uFlags    What meta keys are currently pressed, ignored.
  1166. //                cpPoint    The point at which the mouse was clicked in relative to the upper left corner of the window.
  1167. //    Returns:    void
  1168. //    Comments:    Saves the point in a class member, so other handling can occur through messages generated in the popup.
  1169. //    Revision History:
  1170. //        11-03-95    created CLM
  1171. //
  1172. {
  1173.     MWContext *pMWContext = GET_MWCONTEXT;
  1174.     if( pMWContext == NULL || pMWContext->waitingMode || EDT_IsBlocked(pMWContext) ){
  1175.         return;
  1176.     }
  1177.     // We are getting occasional caret artifacts - clear it here?
  1178.     FE_DestroyCaret(pMWContext);
  1179.  
  1180.     //Note: DON'T Call the base class to handle the click.
  1181.     //  We don't need to do anything in GenView or CWinCX
  1182.  
  1183.     int32 x, y;
  1184.     ClientToDocXY(cpPoint, &x, &y);
  1185.     LO_Element *pElement = NULL;
  1186.     BOOL bSelectTableOrCell = FALSE;
  1187.  
  1188.     m_bAutoSelectObject = FALSE;
  1189.  
  1190.     // Check if clicking on a Table or Cell selection point
  1191.     LO_Element * pTableElement = NULL;
  1192.     BOOL bSizeTable = FALSE;
  1193.  
  1194.     ED_HitType iTableHit = ED_HIT_NONE;
  1195.  
  1196.     // Right Button down: Check if we can select or size a Table or Cell,
  1197.     //   but not if Alt key is pressed, ignore the table
  1198.     //   to allow sizing objects tightly surrounded by Cell border
  1199.     if( !(uFlags & MK_ALT))
  1200.     {
  1201.         iTableHit = EDT_GetTableHitRegion(pMWContext, x, y, &pTableElement, (uFlags & MK_CONTROL) );
  1202.     }
  1203.  
  1204.     if( pTableElement && iTableHit != ED_HIT_NONE )
  1205.     {
  1206.         // We are selecting a table or cell
  1207.         pElement = pTableElement;
  1208.         // Mouse is in a selectable region for table, row, column, or cell.
  1209.         // If Ctrl key is down and a cell is selected, it is appended to other table cells selected
  1210.         EDT_SelectTableElement(pMWContext, x, y, pTableElement, iTableHit,
  1211.                                (uFlags & MK_CONTROL), (uFlags & MK_SHIFT) );
  1212.         bSelectTableOrCell = TRUE;
  1213.  
  1214.         // Don't select anything else -- just position caret in closest table cell
  1215.         EDT_PositionCaret(pMWContext, x, y);
  1216.     } else {
  1217.         // EDT_GetTableHitRegion kindly returns the cell we clicked in 
  1218.         //  even if we didn't hit one of the edges.
  1219.         // Check if we clicked inbetween cells (pTableElement = LO_TABLE)
  1220.         //  or within a cell that is selected.
  1221.         BOOL bCanSelectObject = TRUE;
  1222.         if( pTableElement && (pTableElement->type == LO_TABLE ||
  1223.             (pTableElement->lo_cell.ele_attrmask & LO_ELE_SELECTED)) )
  1224.         {
  1225.             // Don't select internal object, just
  1226.             //  position the caret within the selected cell
  1227.             //  or in closest cell if pTableElement is a table
  1228.             // Use x, y from element to be sure we position within the table
  1229.             if( pTableElement->type == LO_TABLE )
  1230.             {
  1231.                 // We hit between cells - select the table
  1232.                 iTableHit = ED_HIT_SEL_TABLE;
  1233.  
  1234.                 // We need to adjust hit spot so caret will be placed
  1235.                 //  within the nearest cell (bellow/right)
  1236.                 // If we don't, caret will be postitioned before the table!
  1237.                 // TODO: Write an EDT_ function to find closest cell.
  1238.                 x += (pTableElement->lo_table.inter_cell_space + 2);
  1239.                 y += (pTableElement->lo_table.inter_cell_space + 2);
  1240.  
  1241.                 EDT_PositionCaret(pMWContext, x, y);
  1242.                 EDT_SelectTableElement(pMWContext, 0, 0, pTableElement, iTableHit, FALSE, FALSE);
  1243.                 bSelectTableOrCell = TRUE;
  1244.             } else {
  1245.                 // Get last-selected table region type so 
  1246.                 //  we can show region-specific properties item,
  1247.                 //  even though we will also show character and other property menu items above it
  1248.                 iTableHit = EDT_GetSelectedTableElement(pMWContext, NULL );
  1249.                 EDT_PositionCaret(pMWContext, x, y);
  1250.             }
  1251.         } 
  1252.         else if ( !GetContext()->PtInSelectedRegion(cpPoint, TRUE) )
  1253.         {
  1254.             // We are not over an existing selection
  1255.             //   and not inside a selected cell
  1256.             // Remove any existing selection, move caret to cursor position,
  1257.             //  then start selection. This will select single objects
  1258.             //  such as image or HRule. If no object selected,
  1259.             //  the caret is moved to inside the cell.
  1260.             //  Note: THIS DOES NOT REMOVE TABLE SELECTION!
  1261.             EDT_SelectObject(pMWContext, x, y);
  1262.             if( EDT_IsSelected(pMWContext) )
  1263.             {
  1264.                 // Set flag so we can undo the selection when done with property dialog
  1265.                 m_bAutoSelectObject = TRUE;
  1266.             }
  1267.             // Clear any cell selection if caret isn't inside a selected cell
  1268.             // By not clearing selection if we ARE inside,
  1269.             //   user can do properties on selected cells
  1270.             EDT_ClearCellSelectionIfNotInside(pMWContext);
  1271.         }
  1272.     }
  1273.  
  1274.     //    Save the point of the click.
  1275.     //    Look in popup handlers for the real usage of the cached point.
  1276.     //    Obtain the layout element at that point.
  1277.     m_ptRBDown = cpPoint;    
  1278.     if( !bSelectTableOrCell )
  1279.     {
  1280. #ifdef LAYERS
  1281.         // BUGBUG We need to compositor-based event dispatch in 
  1282.         // this case too.
  1283.         //TODO This is temorary fix for the devcon demo. I'll change this code to dispatch a compositor event when I figure
  1284.         // out how to do it. - kamal 10/4/96 
  1285.         CL_Layer *Layer;
  1286.     
  1287.         // Get the "content" layer handle from the root layer.
  1288.         Layer = CL_GetCompositorRoot(pMWContext->compositor);
  1289.         Layer = CL_GetLayerChildByName(Layer, LO_BODY_LAYER_NAME);
  1290.         Layer = CL_GetLayerChildByName(Layer, LO_CONTENT_LAYER_NAME);
  1291.         pElement = GetLayoutElement(cpPoint, Layer);
  1292. #else
  1293.         pElement = GetLayoutElement(cpPoint);
  1294. #endif
  1295.         if (pElement)
  1296.                m_csRBLink = GetAnchorHref(pElement);
  1297.     }
  1298.  
  1299.     //    Create the popup.
  1300.     CMenu cmPopup;
  1301.     if(cmPopup.CreatePopupMenu() == 0)    {
  1302.         return;
  1303.     }
  1304.     
  1305.     BOOL bIsSelected = bSelectTableOrCell || EDT_IsSelected(pMWContext);
  1306.     BOOL bCanPaste = (0 < GetPriorityClipboardFormat( m_pClipboardFormats, 
  1307.                                           MAX_CLIPBOARD_FORMATS ) );
  1308.     BOOL bHaveLink = !m_csRBLink.IsEmpty();
  1309.     BOOL bInTable = bSelectTableOrCell || EDT_IsInsertPointInTable(pMWContext);
  1310.  
  1311.     // This gives us lots of usefull info, but ONLY if caret is in text
  1312.     //   or selection contains some text
  1313.     EDT_CharacterData *pCharData = EDT_GetCharacterData(pMWContext);
  1314.  
  1315.     // Some of following block is extracted from popup-up handling in Browser
  1316.     // Editor will move caret and do most things differently,
  1317.     //   but we want to use some link and image functions
  1318.     //TODO: DO ANYTHING ON EMBEDED ITEMS???
  1319.     m_csRBEmbed.Empty();
  1320.  
  1321.     UINT uState = MF_ENABLED;
  1322.     UINT uMailtoState = MF_ENABLED; 
  1323.     CString csEntry;
  1324.     UINT nID = 0;
  1325.     UINT nIDS;
  1326.     ED_ElementType type = ED_ELEMENT_NONE;
  1327.     BOOL bOneLink = FALSE;
  1328.     BOOL bNoLinks = FALSE;
  1329.     BOOL bMayHaveManyLinks = FALSE;
  1330.     BOOL bLinkProps = FALSE;
  1331.  
  1332.     if( !bSelectTableOrCell )
  1333.     {
  1334.         // Save link info so we can edit or browse
  1335.         if( pElement )
  1336.             m_csRBImage = GetImageHref(pElement);
  1337.  
  1338.         csEntry.LoadString(IDS_POPUP_LOAD_LINK_EDT);
  1339.         CString csAppend = m_csRBLink;
  1340.     
  1341.         if(bHaveLink) {
  1342.             WFE_CondenseURL(csAppend, 25);
  1343.             csEntry += csAppend;        
  1344.             csAppend.Empty();
  1345.         }
  1346.  
  1347.         //    Need to figure out mailto state, and any other URLs
  1348.         //        that won't make sense in a new window, or with
  1349.         //        save as.
  1350.         if(strnicmp(m_csRBLink, "mailto:", 7) == 0 || strnicmp(m_csRBLink, "telnet:", 7) == 0 ||
  1351.             strnicmp(m_csRBLink, "tn3270:", 7) == 0 || strnicmp(m_csRBLink, "rlogin:", 7) == 0)    {
  1352.             uMailtoState = MF_GRAYED;
  1353.         }
  1354.  
  1355.         // The Context-sensitive items - what object are we on
  1356.         type = EDT_GetCurrentElementType(pMWContext);
  1357.         // If a Table or Cell is selected,
  1358.         //  there can be no other element selected,
  1359.         //  so caret must be at text element
  1360.         if( type >= ED_ELEMENT_TABLE )
  1361.             type = ED_ELEMENT_TEXT;
  1362.  
  1363.         // Get HREF state
  1364.         // We are certain (same HREF across selection or
  1365.         // caret in a link) if mask bit is set
  1366.         if( pCharData && pCharData->mask & TF_HREF )
  1367.         {
  1368.             // We are certain that we have a single HREF 
  1369.             //  throughout entire selection or none at all
  1370.             if( pCharData->values & TF_HREF)
  1371.             {
  1372.                 bOneLink = TRUE;
  1373.             } else {
  1374.                 bNoLinks = TRUE;
  1375.             }
  1376.         } else if( type == ED_ELEMENT_IMAGE && bIsSelected )
  1377.         {
  1378.             // TODO: ltabb bug -- a selected image with no HREF
  1379.             //  should have TF_HREF mask bit set
  1380.             if( bHaveLink )
  1381.             {
  1382.                 bOneLink = TRUE;
  1383.             } else {
  1384.                 bNoLinks = TRUE;
  1385.             }
  1386.         } else {
  1387.             // We are uncertain (mixed selection with 
  1388.             // at least 1 HREF found) if mask bit is clear
  1389.             // THIS IS NOT CORRECT if we have only images selected
  1390.             bMayHaveManyLinks = TRUE;
  1391.             // csRBLink should be EMPTY, right? TEST THIS!
  1392.         } 
  1393.  
  1394.         switch( type )
  1395.         {
  1396.             case ED_ELEMENT_IMAGE:
  1397.                 if(bHaveLink)
  1398.                 {
  1399.                     nIDS = IDS_PROPS_IMAGE_LINK;
  1400.                 } else {
  1401.                     nIDS = IDS_PROPS_IMAGE;
  1402.                 }
  1403.                 nID = ID_PROPS_IMAGE;
  1404.                 break;
  1405.             case ED_ELEMENT_HRULE:
  1406.                 nIDS = IDS_PROPS_HRULE;
  1407.                 nID = ID_PROPS_HRULE;
  1408.                 break;
  1409.             case ED_ELEMENT_TARGET:
  1410.                 nIDS = IDS_PROPS_TARGET;
  1411.                 nID = ID_PROPS_TARGET;
  1412.                 break;
  1413.                 // TODO: ADD TARGET, JAVA, PLUG-IN and FORM ELEMENTS
  1414.             case ED_ELEMENT_UNKNOWN_TAG:
  1415.                 nIDS = IDS_PROPS_TAG;
  1416.                 nID =ID_PROPS_TAG;
  1417.                 break;
  1418.             default:    // This is also used when table or cell is element type
  1419.             //case ED_ELEMENT_TEXT:
  1420.             //case ED_ELEMENT_SELECTION:
  1421.  
  1422.                 // We automatically select a link with right mouse down,
  1423.                 //  so check if we are in a link. BUT WHAT ABOUT MIXED SELECTION!
  1424.                 // TODO: TEST THIS IF SELECTION STARTS IN LINK VS.
  1425.                 //       SELECTION ENDS IN LINKS
  1426.                 // TODO: How to Test for IMAGE-ONLY selected block?
  1427.                 if(bHaveLink)
  1428.                 {
  1429.                     nIDS = IDS_PROPS_LINK; 
  1430.                     nID = ID_PROPS_LINK;
  1431.                     bLinkProps = FALSE;
  1432.                 } else if( pCharData )
  1433.                 {    
  1434.                     nIDS = IDS_PROPS_CHARACTER; 
  1435.                     nID = ID_PROPS_CHARACTER;
  1436.                 }
  1437.                 break;            
  1438.         }
  1439.  
  1440.         if ( nID != ID_PROPS_CHARACTER &&
  1441.              !EDT_IsSelected(pMWContext) )
  1442.         {
  1443.             // If no selection, caret is just before an object,
  1444.             //    so also include text properties
  1445.             cmPopup.AppendMenu(MF_ENABLED, ID_PROPS_CHARACTER, szLoadString(IDS_PROPS_CHARACTER));
  1446.         }
  1447.  
  1448.         if( nID )
  1449.         {
  1450.             cmPopup.AppendMenu(MF_ENABLED, nID, szLoadString(nIDS));
  1451.         }
  1452.         // Paragraph props are always available if not table selecting
  1453.         cmPopup.AppendMenu(MF_ENABLED, ID_PROPS_PARAGRAPH,
  1454.                            szLoadString(IDS_PROPS_PARAGRAPH));  
  1455.     
  1456.         // Show "Background and Page Properties" only if not in table
  1457.         if( !bInTable )
  1458.         {
  1459.            cmPopup.AppendMenu(MF_ENABLED, ID_PROPS_DOC_COLOR, szLoadString(IDS_POPUP_PROPS_PAGE));
  1460.         }
  1461.  
  1462.         cmPopup.AppendMenu(MF_SEPARATOR);
  1463.     }
  1464.     HMENU hSelectMenu = 0;
  1465.     HMENU hInsertMenu = 0;
  1466.     HMENU hDeleteMenu = 0;
  1467.  
  1468.     if( bInTable )
  1469.     {
  1470.         // Default is "Table Properties" -- first table property page
  1471.         nID = ID_PROPS_TABLE;
  1472.         nIDS = IDS_POPUP_TABLE_PROPS;
  1473.         // If we clicked on specific table region,
  1474.         //    show properties item for that region instead
  1475.         switch( iTableHit )
  1476.         {
  1477.             case ED_HIT_SEL_TABLE:
  1478.             case ED_HIT_ADD_ROWS:
  1479.             case ED_HIT_ADD_COLS:
  1480.             case ED_HIT_SIZE_TABLE_WIDTH:
  1481.                 break;
  1482.             default:
  1483.                 nID = ID_PROPS_TABLE_CELL;
  1484.                 nIDS = IDS_POPUP_TABLE_CELL_PROPS; 
  1485.                 break;
  1486.  
  1487.         }
  1488.         cmPopup.AppendMenu(uState, nID, szLoadString(nIDS));
  1489.         
  1490.         ED_MergeType MergeType = EDT_GetMergeTableCellsType(pMWContext);
  1491.         if( MergeType != ED_MERGE_NONE )
  1492.         {
  1493.             cmPopup.AppendMenu(MF_ENABLED, ID_MERGE_TABLE_CELLS, 
  1494.                                szLoadString(MergeType == ED_MERGE_NEXT_CELL ? IDS_MERGE_NEXT_CELL : IDS_MERGE_SELECTED_CELLS) );
  1495.         }
  1496. // TODO: IMPLEMENT SPLIT CELL
  1497.         if( EDT_CanSplitTableCell(pMWContext) )
  1498.             cmPopup.AppendMenu(MF_ENABLED, ID_SPLIT_TABLE_CELL, szLoadString(IDS_SPLIT_TABLE_CELL));
  1499.  
  1500.  
  1501.         // We are in a cell, so we can do Select, Insert and Delete table commands,
  1502.         // Use menus shared with Frame's Table Menu
  1503.         hInsertMenu = ::LoadMenu(AfxGetResourceHandle(), MAKEINTRESOURCE(IDM_COMPOSER_TABLE_INSERTMENU));
  1504.         hDeleteMenu = ::LoadMenu(AfxGetResourceHandle(), MAKEINTRESOURCE(IDM_COMPOSER_TABLE_DELETEMENU));
  1505.         hSelectMenu = ::LoadMenu(AfxGetResourceHandle(), MAKEINTRESOURCE(IDM_COMPOSER_TABLE_SELECTMENU));
  1506.         if( hInsertMenu )
  1507.             cmPopup.AppendMenu(MF_POPUP, (UINT)hInsertMenu, szLoadString(IDS_SUBMENU_INSERT_TABLE));
  1508.         if( hDeleteMenu )
  1509.             cmPopup.AppendMenu(MF_POPUP, (UINT)hDeleteMenu, szLoadString(IDS_SUBMENU_DELETE_TABLE));
  1510.         if( hSelectMenu )
  1511.             cmPopup.AppendMenu(MF_POPUP, (UINT)hSelectMenu, szLoadString(IDS_SUBMENU_SELECT_TABLE));
  1512.  
  1513.         cmPopup.AppendMenu(MF_SEPARATOR);
  1514.     }
  1515.  
  1516.     // Link-related items:
  1517.  
  1518.     BOOL bCanSetHREF = EDT_CanSetHREF(pMWContext);
  1519.     BOOL bLinkPopup = FALSE;
  1520.  
  1521.     if( (type == ED_ELEMENT_TEXT || 
  1522.          type == ED_ELEMENT_SELECTION) &&
  1523.          bHaveLink)
  1524.     {
  1525.         // Open link into a browse window
  1526.         cmPopup.AppendMenu(uMailtoState, ID_POPUP_LOADLINKNEWWINDOW, csEntry);
  1527.  
  1528.         // Open link into an edit window
  1529.         cmPopup.AppendMenu(uMailtoState,ID_POPUP_EDIT_LINK,
  1530.                            szLoadString(IDS_POPUP_EDIT_LINK));
  1531.         bLinkPopup = TRUE;
  1532.     }
  1533.     nIDS = 0;
  1534.     if ( bCanSetHREF )
  1535.     {
  1536.         if( bIsSelected  && bNoLinks ){
  1537.             // We have selection and no current link
  1538.             nIDS = IDS_POPUP_CREATE_LINK;
  1539.         }
  1540.     } else if( !bSelectTableOrCell )
  1541.     {
  1542.         // We are in non-link text and don't have a selection
  1543.         nIDS = IDS_POPUP_INSERT_LINK;
  1544.     }
  1545.     if(nIDS)
  1546.     {
  1547.         // Why on earth does ID_PROPS_LINK get disabled if used here???
  1548.         cmPopup.AppendMenu(MF_ENABLED, ID_POPUP_PROPS_LINK, szLoadString(nIDS));
  1549.         bLinkPopup = TRUE;
  1550.     }
  1551.  
  1552.     if( (type == ED_ELEMENT_TEXT ||
  1553.          type == ED_ELEMENT_SELECTION) )
  1554.     {
  1555.         if( bOneLink )
  1556.         {
  1557.             // We are in an existing link with TEXT, not image
  1558.             cmPopup.AppendMenu(uState, ID_POPUP_ADDLINK2BOOKMARKS, 
  1559.                                szLoadString(IDS_POPUP_ADDLINK2BOOKMARKS_EDT));
  1560.             cmPopup.AppendMenu(uState, ID_POPUP_COPYLINKCLIPBOARD,
  1561.                                szLoadString(IDS_POPUP_COPYLINKCLIPBOARD_EDT));
  1562.             // "Remove Link" for single text link
  1563.             cmPopup.AppendMenu(uState, ID_REMOVE_LINKS,
  1564.                                szLoadString(IDS_REMOVE_LINK));
  1565.             bLinkPopup = TRUE;
  1566.         } else if( bMayHaveManyLinks )
  1567.         {
  1568.             // "Remove All Links" for mixed selection
  1569.             cmPopup.AppendMenu(uState, ID_REMOVE_LINKS,
  1570.                                szLoadString(IDS_REMOVE_ALL_LINKS));
  1571.             bLinkPopup = TRUE;
  1572.         } else if( type == ED_ELEMENT_IMAGE )
  1573.         {
  1574.                 // "Remove Link" for single image link
  1575.             cmPopup.AppendMenu(uState, ID_REMOVE_LINKS,
  1576.                                szLoadString(IDS_REMOVE_LINK));
  1577.         }
  1578.     }
  1579.     if(bLinkPopup)
  1580.     {    
  1581.         // End of Link stuff
  1582.         cmPopup.AppendMenu(MF_SEPARATOR);
  1583.     }
  1584.  
  1585.     // Image items:
  1586.     if ( type == ED_ELEMENT_IMAGE )
  1587.     {
  1588.         char *pImageEditor = NULL;
  1589.         PREF_CopyCharPref("editor.image_editor",&pImageEditor);
  1590.         
  1591.         // Add "Edit Image..." if editor was designated
  1592.         // TODO: USE IDS_EDIT_IMAGE FOR VERSION 5.0 (String is missing for 4.0x)
  1593.         if( pImageEditor && XP_STRLEN(pImageEditor) > 0 )
  1594.         {
  1595.             cmPopup.AppendMenu(MF_ENABLED, ID_POPUP_EDIT_IMAGE,
  1596.                                szLoadString(IDS_EDIT_IMAGE));
  1597.         }
  1598.         // "Save image as..."
  1599.         cmPopup.AppendMenu(MF_ENABLED, ID_POPUP_SAVEIMAGEAS,
  1600.                            szLoadString(IDS_EDIT_SAVE_IMAGE));
  1601.  
  1602.         // We don't support background image in the Mail compose window
  1603.         if( !pMWContext->bIsComposeWindow )
  1604.         {
  1605.             // Make the selected image into the background of entire page
  1606.             cmPopup.AppendMenu(MF_ENABLED, ID_MAKE_IMAGE_BACKGROUND,
  1607.                                szLoadString(IDS_POPUP_MAKE_IMAGE_BACKGROUND));
  1608.         }
  1609.         // Add separator from copy/cut/paste items
  1610.         // It will be removed if none of those are used
  1611.         cmPopup.AppendMenu(MF_SEPARATOR);
  1612.         XP_FREEIF(pImageEditor);
  1613.     }
  1614.  
  1615.     if( type == ED_ELEMENT_TEXT )
  1616.     {
  1617.         cmPopup.AppendMenu(MF_ENABLED, ID_COPY_STYLE, szLoadString(IDS_COPY_STYLE));
  1618.     }
  1619.  
  1620.     if ( bIsSelected )
  1621.     {
  1622.         cmPopup.AppendMenu(MF_ENABLED, ID_EDIT_CUT, szLoadString(IDS_EDIT_CUT));
  1623.         cmPopup.AppendMenu(MF_ENABLED, ID_EDIT_COPY, szLoadString(IDS_EDIT_COPY));
  1624.     }
  1625.     if ( bCanPaste )
  1626.     {
  1627.         if ( IsClipboardFormatAvailable( RegisterClipboardFormat(NETSCAPE_BOOKMARK_FORMAT)) )
  1628.         {
  1629.             nID = IDS_EDIT_PASTE_LINK;
  1630.         } else {
  1631.             nID = IDS_EDIT_PASTE;
  1632.         }
  1633.         cmPopup.AppendMenu(MF_ENABLED, ID_EDIT_PASTE, szLoadString(nID));
  1634.     }
  1635.  
  1636.     // Remove last item if its a separator
  1637.     int iLastItem = cmPopup.GetMenuItemCount() - 1;
  1638.     if( iLastItem > 0 && 0 == cmPopup.GetMenuItemID(iLastItem) )
  1639.     {
  1640.         cmPopup.RemoveMenu(iLastItem, MF_BYPOSITION);
  1641.     }
  1642.  
  1643.     //    Track the popup now.
  1644.     ClientToScreen(&cpPoint);
  1645.     
  1646.     // This flag needed to prevent mouse-over message 
  1647.     //    to CWinCX from changing cursor (menu should change it to default arrow)
  1648.     GetContext()->m_bInPopupMenu = TRUE;
  1649.  
  1650.     cmPopup.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, cpPoint.x, cpPoint.y, 
  1651.                            GetParentFrame(), NULL);
  1652.  
  1653.     // If we automatically caused a selection, then clear it now
  1654.     //  so user doesn't accidentally delete our selected object.
  1655.     // Also avoids selected object at same time as selected table or cell
  1656.     if( m_bAutoSelectObject && EDT_IsSelected(pMWContext) ){
  1657.         EDT_ClearSelection(pMWContext);
  1658.         // Don't clear flag yet - done during 
  1659.         m_bAutoSelectObject = FALSE;
  1660.     }
  1661.  
  1662.     GetContext()->m_bInPopupMenu = FALSE;
  1663.  
  1664.     if( hSelectMenu) ::DestroyMenu(hSelectMenu);
  1665.     if( hInsertMenu) ::DestroyMenu(hInsertMenu);
  1666.     if( hDeleteMenu) ::DestroyMenu(hDeleteMenu);
  1667.     if( pCharData ) EDT_FreeCharacterData(pCharData);
  1668. }
  1669.  
  1670. ////////////////////////////////////////////////////////////////////////////
  1671. // This is called when loading images
  1672. // Does not show up if image is already in cache or local file,
  1673. //   needed primarily for remote file loading
  1674. void FE_ImageLoadDialog( MWContext *pMWContext )
  1675. {
  1676.     if ( !pMWContext ){
  1677.         return;
  1678.     }
  1679.  
  1680.     CNetscapeEditView* pView = (CNetscapeEditView*)WINCX(pMWContext)->GetView();
  1681.     // Initialize start time
  1682.     if ( pView->m_nLoadingImageCount == 0) {
  1683.         pView->m_ctStartLoadingImageTime = CTime::GetCurrentTime();
  1684.     
  1685.         // Disable clicking during image loading
  1686.         // CAN'T DO THIS? Seems to interfere with image loading sometimes.
  1687.         pMWContext->waitingMode = TRUE;
  1688.  
  1689.         // Start a timer to pause 3 seconds before 
  1690.         //  poping up dialog
  1691.         ::SetTimer(PANECX(pMWContext)->GetPane(), 
  1692.                     FEED_IMAGE_LOAD_PAUSE, 3000, NULL);
  1693.     }
  1694.     pView->m_nLoadingImageCount++;
  1695. }
  1696.  
  1697. void FE_ImageLoadDialogDestroy( MWContext *pMWContext )
  1698. {
  1699.     if ( !pMWContext ){
  1700.         return;
  1701.     }
  1702.     CNetscapeEditView* pView = (CNetscapeEditView*)WINCX(pMWContext)->GetView();
  1703.     if ( pView->m_nLoadingImageCount ){
  1704.         pView->m_nLoadingImageCount--;
  1705.  
  1706.         if ( pView->m_nLoadingImageCount == 0 && 
  1707.              pView->m_pLoadingImageDlg )
  1708.         {
  1709.             // We're done loading - kill dialog if it exists
  1710.             if( ::IsWindow(pView->m_pLoadingImageDlg->m_hWnd) ){
  1711.                 pView->m_pLoadingImageDlg->DestroyWindow();
  1712.             }
  1713.             pView->m_pLoadingImageDlg = NULL;
  1714.             // Enable clicking
  1715.             pMWContext->waitingMode = FALSE;
  1716.             ::KillTimer(PANECX(pMWContext)->GetPane(), FEED_IMAGE_LOAD_PAUSE);
  1717.         }
  1718.     }
  1719. }
  1720.  
  1721. void FE_FinishedSave( MWContext *pMWContext, int status, 
  1722.                       char *pURL, int m_iCurFile )
  1723. {
  1724.     CNetscapeView* pView = (CNetscapeView*)WINCX(pMWContext)->GetView();
  1725.     if( !pView )
  1726.         return;
  1727.  
  1728.     if( EDT_IS_EDITOR(pMWContext)){ 
  1729.         CNetscapeEditView * pEditView = (CNetscapeEditView*)pView;
  1730.  
  1731.         if (status == ED_ERROR_NONE || status == ED_ERROR_FILE_EXISTS) {
  1732.             if( pEditView->m_pImagePage ){
  1733.                 pEditView->m_pImagePage->SetImageFileSaved(pURL, m_iCurFile);
  1734.             } else if( pEditView->m_pColorPage ){
  1735.                 pEditView->m_pColorPage->SetImageFileSaved(pURL);
  1736.             }
  1737.  
  1738.         }
  1739.     }
  1740.  
  1741. #if 0
  1742.         // *** TODO: We need to inform SiteManager about all URLs published
  1743.         // Tell site manager when each file is published
  1744.         if ( bSiteManagerIsActive &&
  1745.              pView->m_pSaveFileDlg &&
  1746.              ::IsWindow(pView->m_pSaveFileDlg->m_hWnd) &&
  1747.              pView->m_pSaveFileDlg->m_bUpload )
  1748.         {
  1749.             pITalkSMClient->SavedURL(pURL);
  1750.         }
  1751. #endif
  1752. }
  1753.  
  1754. // Note: This is used by Navigator's HTP UPLOAD as well as Composer's file saving
  1755. //  DON'T ASSUME ANY EDITOR FUNCTIONALITY!
  1756. // Dialog to give feedback and allow canceling, overwrite protection
  1757. //   when downloading remote files 
  1758. //
  1759. void FE_SaveDialogCreate( MWContext *pMWContext, int iFileCount, ED_SaveDialogType saveType  )
  1760. {
  1761.     CNetscapeView* pView = (CNetscapeView*)WINCX(pMWContext)->GetView();
  1762.     if( !pView )
  1763.         return;
  1764.  
  1765.     // Get the active child of the current view,
  1766.     //  since we might be called while another dialog box is active
  1767.     CWnd *pParent = pView->GetFrame()->GetFrameWnd()->GetLastActivePopup();
  1768.  
  1769.     pView->m_pSaveFileDlg = new CSaveFileDlg(pParent, pMWContext, iFileCount, saveType);
  1770. }
  1771.  
  1772. void FE_SaveDialogSetFilename( MWContext *pMWContext, char *pFilename )
  1773. {
  1774.     CNetscapeEditView* pView = (CNetscapeEditView*)WINCX(pMWContext)->GetView();
  1775.     
  1776.     // Write the filename into the dialog, but check if it still exists first
  1777.     if ( pView && pView->m_pSaveFileDlg && ::IsWindow(pView->m_pSaveFileDlg->m_hWnd) ){
  1778.         pView->m_pSaveFileDlg->StartFileSave(pFilename);
  1779.     }
  1780. }
  1781.  
  1782. void FE_SaveDialogDestroy( MWContext *pMWContext, int status, char *pFileURL )
  1783. {
  1784.     CNetscapeEditView* pView = (CNetscapeEditView*)WINCX(pMWContext)->GetView();
  1785.     if( !pView ){
  1786.         return;
  1787.     }
  1788.  
  1789.     if( EDT_IS_EDITOR(pMWContext) ) {
  1790.         // Set status value -- Asynchronous start of SaveFile is waiting for this
  1791.         ((CNetscapeEditView*)pView)->SetFileSaveStatus((ED_FileError)status);
  1792.     }
  1793.  
  1794.     int  iCount = 0;
  1795.     BOOL bUpload =  FALSE;
  1796.     
  1797.     if( pView->m_pSaveFileDlg ) {
  1798.  
  1799.         // This gets destroyed if parent wasn't the view
  1800.         //  (e.g., DocProperties dialog)
  1801.         if( ::IsWindow(pView->m_pSaveFileDlg->m_hWnd) ){
  1802.             iCount = pView->m_pSaveFileDlg->m_iFileCount;
  1803.             bUpload = pView->m_pSaveFileDlg->m_bUpload;
  1804.             pView->m_pSaveFileDlg->DestroyWindow();
  1805.         }
  1806.         pView->m_pSaveFileDlg = NULL;
  1807.     }
  1808. #ifdef XP_WIN32
  1809.     if( !bUpload && status == 0 || status == MK_DATA_LOADED ){
  1810.         // Always tell Site Manager about any local files saved
  1811.         // Tell SiteManager we saved a file
  1812.         if( bSiteMgrIsActive &&  status == ED_ERROR_NONE ){
  1813.             pITalkSMClient->SavedURL(pFileURL);
  1814.         }
  1815.     }
  1816. #endif
  1817. }
  1818.  
  1819. ED_SaveOption FE_SaveFileExistsDialog( MWContext *pMWContext, char* pFilename )
  1820. {
  1821.  
  1822.     CNetscapeEditView* pView = (CNetscapeEditView*)WINCX(pMWContext)->GetView();
  1823.     ASSERT(pView && pView->GetFrame() && EDT_IS_EDITOR(pMWContext));
  1824.  
  1825.     CSaveFileOverwriteDlg dlg( pView->GetFrame()->GetFrameWnd()->GetLastActivePopup(), pFilename);
  1826.     dlg.DoModal();
  1827.     return dlg.m_Result;
  1828. }
  1829.  
  1830. // NO LONGER USED NEED TO REMOVE FROM fe_proto.h and all front ends at same time.
  1831. Bool FE_SaveErrorContinueDialog( MWContext *pMWContext, char* pFileName, 
  1832.                                  ED_FileError error )
  1833. {
  1834.     return FALSE;
  1835. }
  1836.  
  1837. /* 
  1838.  * LTNOTE: this should probably be introduced at the usual fifty layers....
  1839. */
  1840. // This doesn't seem to be called at all?
  1841. #if 0
  1842. void FE_ClearBackgroundImage( MWContext *pMWContext ){
  1843.     CNetscapeEditView* pView = (CNetscapeEditView*)WINCX(pMWContext)->GetView();
  1844.     pView->GetContext()->m_pBackdropLOImage = NULL;
  1845.     pView->GetContext()->m_pBackdropILImage = NULL;
  1846. }
  1847. #endif
  1848.  
  1849. PUBLIC Bool FE_EditorPrefConvertFileCaseOnWrite( ){
  1850.     return TRUE;
  1851. }
  1852.  
  1853.  
  1854. void CNetscapeEditView::OnTimer(UINT nIDEvent)
  1855. {
  1856.     CNetscapeView::OnTimer(nIDEvent);
  1857.     if ( nIDEvent == FEED_IMAGE_LOAD_PAUSE &&
  1858.          GET_MWCONTEXT != NULL && 
  1859.          m_nLoadingImageCount > 0 &&
  1860.          m_pLoadingImageDlg == NULL )      // Dialog must not already exist
  1861.     {
  1862.         // Don't need timer any more
  1863.         ::KillTimer(this->m_hWnd, FEED_IMAGE_LOAD_PAUSE);
  1864.  
  1865.         // Create our dialog
  1866.         m_pLoadingImageDlg = new CLoadingImageDlg(GET_DLG_PARENT(this), GET_MWCONTEXT);
  1867.     }
  1868. }
  1869.  
  1870. // This will insert a new image if current element is not an image
  1871. void CNetscapeEditView::OnImagePropDlg()
  1872. {
  1873.     EDT_ImageData* pData = NULL;
  1874.     
  1875.     if (EDT_GetCurrentElementType(GET_MWCONTEXT) == ED_ELEMENT_IMAGE){
  1876.         pData = EDT_GetImageData(GET_MWCONTEXT);
  1877.     }
  1878. }
  1879.  
  1880. /////////////////////////////////////////////////
  1881. void CNetscapeEditView::OnInsertHRule()
  1882. {
  1883.     MWContext * pMWContext = GET_MWCONTEXT;
  1884.     if( pMWContext ){
  1885.         // Edit properties of existing HRule if it is the selected object
  1886.         if( ED_ELEMENT_HRULE == EDT_GetCurrentElementType(pMWContext) ) {
  1887.             OnHRuleProperties();
  1888.             return;
  1889.         }
  1890.         // Hrule is so simple, just use default values
  1891.         //   instead of bringing up properties dialog
  1892.         EDT_HorizRuleData *pData = EDT_NewHorizRuleData();
  1893.         if ( pData ){
  1894.             // Unselect so we insert after after the object
  1895.             if( NonLinkObjectIsSelected(pMWContext) )
  1896.                 EDT_ClearSelection(pMWContext);
  1897.             
  1898.             // Get defaults from preferences
  1899.             int32 iWidth,iHeight;
  1900.  
  1901.             PREF_GetIntPref("editor.hrule.height",&iHeight);
  1902.             PREF_GetIntPref("editor.hrule.width",&iWidth);
  1903.             PREF_GetBoolPref("editor.hrule.width_percent",&(pData->bWidthPercent));
  1904.             // Confusing! Pref and UI use "Shading" but tag param is NOSHADE
  1905.             BOOL bShading;
  1906.             PREF_GetBoolPref("editor.hrule.shading",&bShading);
  1907.             pData->bNoShade = !bShading;
  1908.  
  1909.             pData->size = iHeight;
  1910.             pData->iWidth = iWidth;
  1911.  
  1912.             int32 align;
  1913.             PREF_GetIntPref("editor.hrule.align",&align);
  1914.             
  1915.             if( align == ED_ALIGN_RIGHT ){
  1916.                 pData->align = ED_ALIGN_RIGHT;
  1917.             } else if( align == ED_ALIGN_LEFT  ){
  1918.                 pData->align = ED_ALIGN_LEFT;
  1919.             } else {
  1920.                 pData->align = ED_ALIGN_CENTER;
  1921.             }
  1922.  
  1923.             EDT_InsertHorizRule(pMWContext, pData);
  1924.             EDT_FreeHorizRuleData(pData);
  1925.         }
  1926.     }
  1927. #if 0
  1928.     // Save this in case we want to popu properties dialog after
  1929.     //   inserting new HRULE - maybe a user preference?
  1930.     // All the work is done by the dialog
  1931.     // supply no data to insert new rule
  1932.     CHRuleDlg dlg(GET_DLG_PARENT(this), pMWContext);
  1933.     dlg.DoModal();
  1934. #endif
  1935. }
  1936.  
  1937. // This will insert a new HRule if current element is not an image
  1938. void CNetscapeEditView::OnHRuleProperties()
  1939. {
  1940.     EDT_HorizRuleData* pData = NULL;
  1941.     if (EDT_GetCurrentElementType(GET_MWCONTEXT) == ED_ELEMENT_HRULE){
  1942.         pData = EDT_GetHorizRuleData(GET_MWCONTEXT);
  1943.     }
  1944.     CHRuleDlg dlg(GET_DLG_PARENT(this), GET_MWCONTEXT, pData);
  1945.     dlg.DoModal();
  1946. }
  1947.  
  1948. void CNetscapeEditView::OnUpdateHRuleProperties(CCmdUI* pCmdUI)
  1949. {
  1950.     // In menu, properties does not allow insert,
  1951.     //  so we check object type
  1952.     // Toolbar button does Insert or Change existing properties
  1953.     if (pCmdUI->m_pMenu ) {
  1954.         pCmdUI->Enable(CAN_INTERACT && 
  1955.                        EDT_GetCurrentElementType(GET_MWCONTEXT) == ED_ELEMENT_HRULE);
  1956.     } else {
  1957.         pCmdUI->Enable(CAN_INTERACT);
  1958.     }
  1959. }
  1960.  
  1961. ////////////////////////////////////////////////////
  1962. // Tabbed Dialog Property UI:
  1963.  
  1964. #define PROPS_PAGE_TEXT_OR_IMAGE  0
  1965. #define PROPS_PAGE_LINK           1
  1966. #define PROPS_PAGE_PARA           2
  1967.  
  1968. void CNetscapeEditView::OnUpdatePropsLocal(CCmdUI* pCmdUI)
  1969. {
  1970.     // We only have this on the menu
  1971.     if( !pCmdUI->m_pMenu )
  1972.         return;
  1973.  
  1974.     MWContext *pMWContext = GET_MWCONTEXT;
  1975.     if( !pMWContext )
  1976.         return;
  1977.  
  1978.     UINT nID = 0;
  1979.     ED_ElementType ElementType = ED_ELEMENT_NONE;
  1980.  
  1981.     // Check for the last table object selected
  1982.     ED_HitType iHit =  EDT_GetSelectedTableElement(pMWContext, NULL);
  1983.     if( iHit )
  1984.     {
  1985.         switch( iHit )
  1986.         {
  1987.             case ED_HIT_SEL_ROW:
  1988.                 nID = IDS_POPUP_TABLE_PROPS;
  1989.                 break;
  1990.             case ED_HIT_SEL_COL:
  1991.                 nID = IDS_POPUP_TABLE_PROPS;
  1992.                 break;
  1993.             case ED_HIT_SEL_CELL:
  1994.                 nID = IDS_POPUP_TABLE_PROPS;
  1995.                 break;
  1996.         }
  1997.     } else {
  1998.         ElementType = EDT_GetCurrentElementType(pMWContext);
  1999.         switch ( ElementType ){
  2000.             case ED_ELEMENT_IMAGE:
  2001.                 nID = IDS_PROPS_IMAGE;
  2002.                 break;
  2003.             case ED_ELEMENT_HRULE:
  2004.                 nID = IDS_PROPS_HRULE;
  2005.                 break;
  2006.             case ED_ELEMENT_TARGET:
  2007.                 nID = IDS_PROPS_TARGET;
  2008.                 break;
  2009.             case ED_ELEMENT_UNKNOWN_TAG:
  2010.                 nID = IDS_PROPS_TAG;
  2011.                 break;
  2012.             default:
  2013.                 nID = IDS_PROPS_CHARACTER;
  2014.                 break;
  2015.         }
  2016.     }
  2017.     if( nID )
  2018.     {
  2019.         char pMenu[256];
  2020.         strcpy(pMenu, szLoadString(nID));
  2021.         strcat(pMenu, szLoadString(IDS_ALT_ENTER));
  2022.         pCmdUI->m_pMenu->ModifyMenu(ID_PROPS_LOCAL, MF_BYCOMMAND | MF_STRING, ID_PROPS_LOCAL,
  2023.                                     pMenu);
  2024.     }
  2025.     // Use this to suppress char props when uncertain,
  2026.     pCmdUI->Enable(CAN_INTERACT);
  2027.  
  2028.     // Enable/Disable the "Make image the background" menu item        
  2029.     pCmdUI->m_pMenu->EnableMenuItem(ID_MAKE_IMAGE_BACKGROUND,
  2030.                                     ElementType == ED_ELEMENT_IMAGE ? MF_ENABLED : MF_GRAYED);
  2031.  
  2032. }
  2033.  
  2034. // Call this from toolbar or popup menu (right mouse button)
  2035. void CNetscapeEditView::OnLocalProperties()
  2036. {
  2037.     MWContext *pMWContext = GET_MWCONTEXT;
  2038.     if( !pMWContext )
  2039.         return;
  2040.  
  2041.     // Check for last table hit area
  2042.     ED_HitType iHit =  EDT_GetTableHitRegion(pMWContext, -1, -1, NULL, FALSE);
  2043.     int iStartPage = -1;
  2044.     switch( iHit )
  2045.     {
  2046.         case ED_HIT_SEL_TABLE:
  2047.         case ED_HIT_ADD_ROWS:
  2048.         case ED_HIT_ADD_COLS:
  2049.         case ED_HIT_SIZE_TABLE_WIDTH:
  2050.             // Allow any of 4 corners to select table properties
  2051.             iStartPage = 0;
  2052.             break;
  2053.         default:
  2054.             iStartPage = 1;   // The Cell Properties page
  2055.             break;
  2056.     }
  2057.     if( iStartPage >= 0 )
  2058.     {
  2059.         OnTableProperties(iStartPage);
  2060.         return;
  2061.     }
  2062.  
  2063.     ED_ElementType type = EDT_GetCurrentElementType(pMWContext);
  2064.     switch( type ) {
  2065.         case ED_ELEMENT_IMAGE:
  2066.             OnImageProperties();
  2067.             break;
  2068.         case ED_ELEMENT_HRULE:
  2069.             OnHRuleProperties();
  2070.             break;
  2071.         case ED_ELEMENT_TARGET:
  2072.             OnTargetProperties();
  2073.             break;
  2074.         case ED_ELEMENT_UNKNOWN_TAG:
  2075.             OnTagProperties();
  2076.             break;
  2077.         default:
  2078.             // Here if element = text or unknown (multiple/selected)
  2079.             if(EDT_CanSetHREF(GET_MWCONTEXT)){
  2080.                 // Do link properties if we are in a link
  2081.                 CString m_csHref = EDT_GetHREF(pMWContext);
  2082.                 if(!m_csHref.IsEmpty()){
  2083.                     DoProperties(PROPS_PAGE_LINK);
  2084.                     break;
  2085.                 }
  2086.             }
  2087.             // If here, we are in text or unknown selection
  2088.             OnTextProperties();
  2089.             break;
  2090.     }
  2091. }
  2092.  
  2093. // Central processing for common property page system
  2094. //
  2095. void CNetscapeEditView::DoProperties(int iStartPage, UINT nIDFirstTab)
  2096. {
  2097.     MWContext * pMWContext = GET_MWCONTEXT;
  2098.     if (pMWContext == NULL || !EDT_IS_EDITOR(pMWContext)) {
  2099.         return;
  2100.     }
  2101.     BOOL   bImage = FALSE;
  2102.     BOOL   bInsertLink = FALSE;
  2103.     BOOL   bInsertImage = FALSE;
  2104.     char **ppLinkImage = NULL;
  2105.     ED_ElementType type = EDT_GetCurrentElementType(pMWContext);
  2106.  
  2107.     if( nIDFirstTab > 0 )
  2108.     {
  2109.         bImage = (nIDFirstTab == IDD_PAGE_IMAGE);
  2110.     } else {
  2111.         bImage = (type == ED_ELEMENT_IMAGE);
  2112.     }
  2113.     // Figure out context: what is object we are in and/or selected
  2114.  
  2115.     // Get or create object data
  2116.     EDT_ImageData     *pImageData = NULL;
  2117.     EDT_HREFData      *pHrefData = NULL;
  2118.     EDT_CharacterData *pCharData = NULL;
  2119.     BOOL               bMayHaveOtherLinks = FALSE;
  2120.     
  2121.     if(bImage){
  2122.         if( type == ED_ELEMENT_IMAGE ) {
  2123.             pImageData = EDT_GetImageData(pMWContext);
  2124.         }
  2125.         if(pImageData == NULL){
  2126.             // Create a new structure to insert an image
  2127.             pImageData = EDT_NewImageData();
  2128.             if(pImageData == NULL){
  2129.                 // Something is really wacked!
  2130.                 return;
  2131.             }
  2132.             bInsertImage = TRUE;
  2133.         }
  2134.         //GetImageData is not filling this in yet,
  2135.         //   it will work when it does...
  2136.         // Set pointer so Link Dialog uses the data from the Image
  2137.         pHrefData = pImageData->pHREFData;
  2138.         // This will be used by Link Dialog to show the Image filename
  2139.         // If it is changed by Image Dialog, Link will update correctly
  2140.         ppLinkImage = &pImageData->pSrc;
  2141.     } else {
  2142.         // First page will be Character page
  2143.         pCharData = EDT_GetCharacterData(pMWContext);
  2144.         if( pCharData ){
  2145.             // If HREF flag is indeterminate
  2146.             // (i.e., the mask bit is not set),
  2147.             //  then there may be other links we can remove
  2148.             bMayHaveOtherLinks = (pCharData->mask & TF_HREF) == 0;
  2149.         
  2150.             // By design, we NEVER change HREF data in Character dialog,
  2151.             //   so clear HREF mask bit so we don't change it.
  2152.             //   bMayHaveOtherLinks will allow Link page to remove 
  2153.             //   link attributes from the text selection via Remove Link button.
  2154.             pCharData->mask &= ~TF_HREF;
  2155.         } else {
  2156.             // We should never get here!
  2157.             // We should identify the selected object,
  2158.             //    or we are left with text or mixed selection
  2159.             return;
  2160.         }
  2161.     }
  2162.     
  2163.     // This will, of course, be true when we don't have an image
  2164.     if(pHrefData == NULL){
  2165.         // Get HREF data from current element
  2166.         pHrefData = EDT_GetHREFData(pMWContext);
  2167.         if(pHrefData && pHrefData->pURL == NULL){
  2168.             // No current link -- we will insert one
  2169.             bInsertLink = TRUE;
  2170.         }
  2171.     }
  2172.     if(pHrefData == NULL){
  2173.         // Should never happen unless memory allocation failed
  2174.         return;
  2175.     }
  2176.  
  2177.     // Use other HREF data if GetImageData didn't supply any
  2178.     if(bImage && pImageData->pHREFData == NULL){
  2179.         pImageData->pHREFData = pHrefData;
  2180.         ppLinkImage = &pImageData->pSrc;
  2181.     }
  2182.  
  2183.     // Create the sheet with generic "Properties" caption
  2184.     // TODO: Should we bother to change this on context?
  2185.     CNetscapePropertySheet PropsDlg(szLoadString(CASTUINT(bImage ? IDS_IMAGE_PROPS_CAPTION : IDS_TEXT_PROPS_CAPTION)),
  2186.                                     GET_DLG_PARENT(this), 0, pMWContext, TRUE); // Use the Apply Button
  2187.  
  2188.     CCharacterPage * CharacterPage = NULL;
  2189.     m_pImagePage = NULL;
  2190.  
  2191.     // This will change resource hInstance to EditorXX.dll (in its constructor)
  2192.     // We pass this into our property page, which resets back to EXE's resources later
  2193.     CEditorResourceSwitcher ResourceSwitcher;
  2194.  
  2195.     // These pages are always used
  2196.     CParagraphPage * ParagraphPage = new CParagraphPage(this, pMWContext, &ResourceSwitcher);
  2197.     CLinkPage * LinkPage =  new CLinkPage(this, pMWContext, &ResourceSwitcher, pHrefData,
  2198.                                           bInsertLink, bMayHaveOtherLinks, ppLinkImage);
  2199.  
  2200.  
  2201.     if(bImage){
  2202.         m_pImagePage = new CImagePage(this, pMWContext, &ResourceSwitcher, pImageData, bInsertImage);
  2203.         PropsDlg.AddPage(m_pImagePage);
  2204.     } else {
  2205.         CharacterPage = new CCharacterPage(this, pMWContext, &ResourceSwitcher, pCharData);
  2206.         PropsDlg.AddPage(CharacterPage);
  2207.     }
  2208.  
  2209.     PropsDlg.AddPage(LinkPage);
  2210.     PropsDlg.AddPage(ParagraphPage);
  2211.  
  2212.     int32 iPrefInt;
  2213.     
  2214.     if ( iStartPage < 0 ) {
  2215.         // Figure out what page to start on
  2216.         if(bImage){
  2217.             iStartPage = 0;
  2218.         } else {
  2219.             // Get last page depending on preferences
  2220.             // NOTE: Only choice now is for Text properites
  2221.             PREF_GetIntPref("editor.last_text_page", &iPrefInt);
  2222.             iStartPage = (int)iPrefInt;
  2223.         }
  2224.     }
  2225.     // Must initially set page to 0 so dialog is sized relative to Image page
  2226.     PropsDlg.SetCurrentPage(0);
  2227.     PropsDlg.SetCurrentPage(iStartPage);
  2228.     
  2229.     if(PropsDlg.DoModal() == IDOK) {
  2230.         int iCurrentPage = PropsDlg.GetCurrentPage();
  2231.         if( iCurrentPage <= 2 ){
  2232.             // Save current page if NOT Link page
  2233.             // Somewhat arbitrary, but seems to 
  2234.             //  make more sense with testing
  2235.             if(iCurrentPage != PROPS_PAGE_LINK){
  2236.                 PREF_GetIntPref("editor.last_text_page", &iPrefInt);
  2237.                 iCurrentPage = (int)iPrefInt;
  2238.             }
  2239.         }
  2240.     }
  2241.     // If we automatically caused a selection, then clear it now
  2242.     //  so user doesn't accidentally delete our selected object.
  2243.     if( m_bAutoSelectObject && EDT_IsSelected(pMWContext) ){
  2244.         EDT_ClearSelection(pMWContext);
  2245.         m_bAutoSelectObject = FALSE;
  2246.     }
  2247.     if(pImageData) {
  2248.         EDT_FreeImageData(pImageData);
  2249.         // pHrefData is a member of pImageData and is freed there
  2250.     } else if(pHrefData) {
  2251.         // We didn't have an Image page -- free link data
  2252.         EDT_FreeHREFData(pHrefData);
  2253.     }
  2254.     if(pCharData) EDT_FreeCharacterData(pCharData);
  2255.  
  2256.     delete ParagraphPage;
  2257.     delete LinkPage;
  2258.     if(CharacterPage){
  2259.         delete CharacterPage;
  2260.     } else if(m_pImagePage){
  2261.         delete m_pImagePage;
  2262.         m_pImagePage = NULL;
  2263.     }
  2264. }
  2265.  
  2266. void CNetscapeEditView::OnImageProperties()
  2267. {
  2268.     DoProperties(PROPS_PAGE_TEXT_OR_IMAGE, IDD_PAGE_IMAGE);
  2269. }
  2270.  
  2271. void CNetscapeEditView::OnLinkProperties()
  2272. {
  2273.     if ( GET_MWCONTEXT ) {
  2274.         // Set first page to Character or Image depending
  2275.         //   on the current object
  2276.         DoProperties(PROPS_PAGE_LINK,
  2277.                      EDT_GetCurrentElementType(GET_MWCONTEXT) == ED_ELEMENT_IMAGE ? 
  2278.                          IDD_PAGE_IMAGE : IDD_PAGE_CHARACTER);
  2279.     }
  2280. }
  2281.  
  2282. void CNetscapeEditView::OnParagraphProperties()
  2283. {
  2284.     DoProperties(PROPS_PAGE_PARA);
  2285. }
  2286.  
  2287. // 10/28/97 Not called currently! (Resource ID = ID_PROPS_TEXT)
  2288. void CNetscapeEditView::OnCharacterProperties()
  2289. {
  2290.     DoProperties(PROPS_PAGE_TEXT_OR_IMAGE, IDD_PROPS_CHARACTER);
  2291. }
  2292.  
  2293. // Same as Character or Paragraph,
  2294. // but start page is same as last use
  2295. void CNetscapeEditView::OnTextProperties()
  2296. {
  2297.     DoProperties(-1, IDD_PROPS_CHARACTER);
  2298. }
  2299.  
  2300.  
  2301. void CNetscapeEditView::OnUpdateImageProperties(CCmdUI* pCmdUI)
  2302. {
  2303.     // In menu, properties does not allow insert,
  2304.     //  so we check object type
  2305.     // Toolbar button does Insert or Change existing properties
  2306.     if (pCmdUI->m_pMenu ) {
  2307.         pCmdUI->Enable(CAN_INTERACT && 
  2308.                        EDT_GetCurrentElementType(GET_MWCONTEXT) == ED_ELEMENT_IMAGE);
  2309.     } else {
  2310.         pCmdUI->Enable(CAN_INTERACT);
  2311.     }
  2312. }
  2313.  
  2314. void CNetscapeEditView::OnUpdateLinkProperties(CCmdUI* pCmdUI)
  2315. {
  2316.     // Must be on an existing link:
  2317.     pCmdUI->Enable( CAN_INTERACT && EDT_GetHREF(GET_MWCONTEXT) );
  2318. }
  2319.  
  2320. // *** Inserting the objects used in common properties
  2321.  
  2322. void CNetscapeEditView::OnInsertImage()
  2323. {
  2324.     MWContext * pMWContext = GET_MWCONTEXT;
  2325.     if( pMWContext ){
  2326.         // Unselect so we insert after after the object
  2327.         if( NonLinkObjectIsSelected(pMWContext) )
  2328.             EDT_ClearSelection(pMWContext);
  2329.         OnImageProperties();
  2330.     }
  2331. }
  2332.  
  2333. void CNetscapeEditView::OnMakeLink()
  2334. {
  2335.     MWContext * pMWContext = GET_MWCONTEXT;
  2336.     // Force saving a new or remote document
  2337.     if( pMWContext ) {
  2338.         // Unselect a single object that can't be a link
  2339.         if( NonLinkObjectIsSelected(pMWContext) ) {
  2340.             EDT_ClearSelection(pMWContext);
  2341.         }
  2342.         OnLinkProperties();
  2343.     }
  2344. }
  2345.  
  2346. void CNetscapeEditView::OnInsertLink()
  2347. {
  2348.     OnMakeLink();
  2349. }
  2350.  
  2351. void CNetscapeEditView::OnUpdateInsertLink(CCmdUI* pCmdUI)
  2352. {
  2353.     MWContext * pMWContext = GET_MWCONTEXT;
  2354.     // To reduce confusion, try to not allow inserting a link
  2355.     //  inside of an exisiting link.
  2356.     // But if selected, we can't know if selection includes an existing link
  2357.     // Action will do a "modify link" rather than insert new link
  2358.     pCmdUI->Enable( CAN_INTERACT &&
  2359.                     (EDT_IsSelected(pMWContext) ||
  2360.                      !EDT_CanSetHREF(pMWContext)) );
  2361. }
  2362.  
  2363. void CNetscapeEditView::OnRemoveLinks()
  2364. {
  2365.     // Remove a single link or all links
  2366.     //  within selected region
  2367.     if( EDT_CanSetHREF(GET_MWCONTEXT) ){
  2368.         EDT_SetHREF(GET_MWCONTEXT, NULL);
  2369.     }
  2370. }
  2371.  
  2372. void CNetscapeEditView::OnUpdateRemoveLinks(CCmdUI* pCmdUI)
  2373. {
  2374.     if( !CAN_INTERACT ) {
  2375.         pCmdUI->Enable(FALSE);
  2376.         return;
  2377.     }
  2378.     MWContext * pMWContext = GET_MWCONTEXT;
  2379.  
  2380.     ED_ElementType type = EDT_GetCurrentElementType(pMWContext);
  2381.  
  2382.     pCmdUI->Enable( (type == ED_ELEMENT_TEXT || type == ED_ELEMENT_SELECTION || 
  2383.                      type == ED_ELEMENT_IMAGE || type >= ED_ELEMENT_TABLE) &&
  2384.                     EDT_CanSetHREF(GET_MWCONTEXT) );
  2385. }
  2386.  
  2387. void CNetscapeEditView::OnSetImageAsBackground()
  2388. {
  2389.     EDT_SetImageAsBackground(GET_MWCONTEXT);
  2390. }
  2391.  
  2392. // End of common property page system
  2393. //
  2394. /////////////////////////////////////////////////////
  2395. //
  2396. void CNetscapeEditView::OnDocColorProperties()
  2397. {
  2398.     OnDocProperties(1);
  2399. }
  2400.  
  2401. void CNetscapeEditView::OnDocumentProperties()
  2402. {
  2403.     OnDocProperties(0);
  2404. }
  2405.  
  2406. void CNetscapeEditView::OnDocProperties(int iStartPage)
  2407. {
  2408.     MWContext * pMWContext = GET_MWCONTEXT;
  2409.     if (pMWContext == NULL) {
  2410.         return;
  2411.     }
  2412.     EDT_PageData * pPageData = EDT_GetPageData(pMWContext);
  2413.     if (pPageData == NULL) {
  2414.         return;
  2415.     }
  2416.     CNetscapePropertySheet Properties( szLoadString(IDS_DOC_PROPS_CAPTION),
  2417.                                     GET_DLG_PARENT(this), 0, pMWContext, TRUE); // Use the Apply Button
  2418.  
  2419.     // This will change resource hInstance to EditorXX.dll (in its constructor)
  2420.     // We pass this into our property page, which resets back to EXE's resources later
  2421.     CEditorResourceSwitcher ResourceSwitcher;
  2422.  
  2423.     CDocInfoPage * pDocInfoPage = NULL;
  2424.     CDocMetaPage * pDocMetaPage = NULL;
  2425.     if( !pMWContext->bIsComposeWindow ){
  2426.         pDocInfoPage = new CDocInfoPage(this, pMWContext, &ResourceSwitcher, pPageData);
  2427.     }
  2428.     // 2nd param is nIDCaption: use dialog caption, 3rd is initial focus ID
  2429.     // 6th param tells dialog to behave like Doc properties, not preference dialog
  2430.     // Note that we keep pointer to this page so XP code can tell us
  2431.     //   what the background image is when it has changed
  2432.     m_pColorPage = new CDocColorPage(this, 0, 0, pMWContext, &ResourceSwitcher, pPageData);
  2433.  
  2434.     if( !pMWContext->bIsComposeWindow ){
  2435.         pDocMetaPage = new CDocMetaPage(this, pMWContext, &ResourceSwitcher);
  2436.         Properties.AddPage(pDocInfoPage);
  2437.     }
  2438.  
  2439.     Properties.AddPage(m_pColorPage);
  2440.     
  2441.     if( !pMWContext->bIsComposeWindow ){
  2442.         Properties.AddPage(pDocMetaPage);
  2443.     }
  2444.     
  2445.     // Set to page passed in or last page accessed
  2446.     int32 iPage=0;
  2447.     if( iStartPage >= 0 && iStartPage < 3 )
  2448.         iPage = iStartPage;
  2449.     else 
  2450.         PREF_GetIntPref("editor.last_doc_page",&iPage);
  2451.     
  2452.     Properties.SetCurrentPage(CASTINT(iPage));
  2453.  
  2454.     Properties.DoModal();
  2455.  
  2456.     // Cleanup - (Must be done in reverse order of AddPage?)
  2457.     if( pDocMetaPage ){
  2458.         delete pDocMetaPage;
  2459.     }
  2460.     if( m_pColorPage ){
  2461.         delete m_pColorPage;
  2462.     }
  2463.     m_pColorPage = NULL;
  2464.     if( pDocInfoPage ){
  2465.         delete pDocInfoPage;
  2466.     }
  2467.     
  2468.     EDT_FreePageData(pPageData);
  2469.  
  2470.     // Save last page accessed
  2471.     PREF_SetIntPref("editor.last_doc_page",Properties.GetCurrentPage());
  2472. }
  2473.  
  2474. ////////////////////////////////////////////////////
  2475. void CNetscapeEditView::OnFormatIndent()
  2476. {
  2477.     MWContext *pMWContext = GET_MWCONTEXT ;
  2478.     if ( pMWContext ){
  2479.         EDT_BeginBatchChanges(pMWContext);
  2480.         EDT_Indent(pMWContext);
  2481.         EDT_EndBatchChanges(pMWContext);
  2482.     }
  2483. }
  2484.  
  2485. void CNetscapeEditView::OnFormatOutdent()
  2486. {
  2487.     MWContext *pMWContext = GET_MWCONTEXT ;
  2488.     if ( pMWContext ){
  2489.         EDT_BeginBatchChanges(pMWContext);
  2490.         EDT_Outdent( GET_MWCONTEXT );
  2491.         EDT_EndBatchChanges(pMWContext);
  2492.     }
  2493. }
  2494.  
  2495. void CNetscapeEditView::OnUnumList()
  2496. {
  2497.     if ( !CAN_INTERACT ){
  2498.         return;
  2499.     }
  2500.     EDT_ToggleList(GET_MWCONTEXT, P_UNUM_LIST);
  2501. }
  2502.  
  2503. void CNetscapeEditView::OnNumList()
  2504. {
  2505.     if ( !CAN_INTERACT ){
  2506.         return;
  2507.     }
  2508.     EDT_ToggleList(GET_MWCONTEXT, P_NUM_LIST);
  2509. }
  2510.  
  2511. void CNetscapeEditView::OnRemoveList()
  2512. {
  2513.     // Repeat removing indent until last Unnumbered list is gone
  2514.     MWContext * pMWContext = GET_MWCONTEXT;
  2515.     if( ! pMWContext ){
  2516.         return;
  2517.     }
  2518.     EDT_RemoveList(pMWContext);
  2519. }
  2520.  
  2521. void CNetscapeEditView::OnUpdateRemoveList(CCmdUI* pCmdUI)
  2522. {
  2523.     EDT_ListData * pListData = EDT_GetListData(GET_MWCONTEXT);
  2524.     pCmdUI->Enable(CAN_INTERACT && pListData);
  2525.     if( pCmdUI->m_pMenu) {
  2526.         pCmdUI->SetCheck(!pListData);
  2527.     }
  2528.     if(pListData){
  2529.         EDT_FreeListData(pListData);
  2530.     }
  2531. }
  2532.  
  2533. void CNetscapeEditView::UpdateListMenuItem(CCmdUI* pCmdUI, TagType t)
  2534. {
  2535.     BOOL bIsList = EDT_GetToggleListState(GET_MWCONTEXT, t);
  2536.  
  2537.     if( pCmdUI->m_pMenu) {
  2538.         pCmdUI->SetCheck(bIsList);
  2539.     }
  2540.     pCmdUI->Enable(CAN_INTERACT);
  2541.  
  2542.     CEditToolBarController * pController = 
  2543.         (CEditToolBarController *)GetParentFrame()->SendMessage(WM_TOOLCONTROLLER);
  2544.     if (pController && CAN_INTERACT && !pCmdUI->m_pMenu && pController->GetCharacterBar() ) {
  2545.             (pController->GetCharacterBar())->SetCheck( pCmdUI->m_nID, bIsList );
  2546.     }
  2547. }
  2548.  
  2549. void CNetscapeEditView::OnUpdateUnumList(CCmdUI* pCmdUI)
  2550. {
  2551.     UpdateListMenuItem(pCmdUI, P_UNUM_LIST);
  2552. }
  2553.  
  2554. void CNetscapeEditView::OnUpdateNumList(CCmdUI* pCmdUI)
  2555. {
  2556.     UpdateListMenuItem(pCmdUI, P_NUM_LIST);
  2557. }
  2558.  
  2559. void CNetscapeEditView::OnBlockQuote()
  2560. {
  2561.     OnFormatParagraph(ID_FORMAT_PARAGRAPH_BASE+P_BLOCKQUOTE);
  2562. }
  2563.  
  2564. void CNetscapeEditView::OnAlignPopup()
  2565. {
  2566.     MWContext * pMWContext = GET_MWCONTEXT;
  2567.     if( ! pMWContext ){
  2568.         return;
  2569.     }
  2570.     ED_ElementType type = EDT_GetCurrentElementType(pMWContext);
  2571.     ED_Alignment old_align = ED_ALIGN_DEFAULT;
  2572.  
  2573.     switch( type )
  2574.     {
  2575.         case ED_ELEMENT_HRULE:
  2576.         {
  2577.             EDT_HorizRuleData* pData = EDT_GetHorizRuleData(pMWContext);
  2578.             if ( pData ){
  2579.                 old_align = pData->align;
  2580.             }
  2581.             break;
  2582.         }
  2583.         case ED_ELEMENT_TABLE:
  2584.             break;
  2585.         case ED_ELEMENT_ROW:
  2586.             break;
  2587.         case ED_ELEMENT_COL:
  2588.         case ED_ELEMENT_CELL:
  2589.             break;
  2590.         default:
  2591.             old_align = EDT_GetParagraphAlign(pMWContext);
  2592.             break;
  2593.     }
  2594.     ED_Alignment align = old_align;
  2595.     
  2596.     RECT rectCaller = {0,0, 0, 0};
  2597.     RECT newRectCaller = {0, 0, 0, 0 };
  2598.     CEditToolBarController * pController = 
  2599.         (CEditToolBarController *)GetParentFrame()->SendMessage(WM_TOOLCONTROLLER);
  2600.     if (pController) {
  2601.         CComboToolBar * pToolbar = pController->GetCharacterBar();
  2602.         CCommandToolbar *pCommandToolbar = pController->GetCNSToolbar();
  2603.        if( pToolbar ){
  2604.             pToolbar->GetButtonRect(ID_ALIGN_POPUP, &rectCaller);
  2605.         }
  2606.        if(pCommandToolbar){
  2607.             pCommandToolbar->GetButtonRect(ID_ALIGN_POPUP, &rectCaller);
  2608.        }
  2609.  
  2610.  
  2611.     }
  2612.     UINT nInitialID = 0;
  2613.     switch (old_align ){
  2614.         case ED_ALIGN_LEFT:
  2615.             nInitialID = ID_ALIGN_LEFT;
  2616.             break;
  2617.         case ED_ALIGN_CENTER:
  2618.         case ED_ALIGN_ABSCENTER:
  2619.             nInitialID = ID_ALIGN_CENTER;
  2620.             break;
  2621.         case ED_ALIGN_RIGHT:
  2622.             nInitialID = ID_ALIGN_RIGHT;
  2623.             break;
  2624.     }
  2625.         
  2626.     pTB = NULL;
  2627.     // Build dropdown toolbar for alignment buttons
  2628.     //   CommandID is sent to parent frame when pressed
  2629.     // Use this to include current state as a push-down button:
  2630.     pTB = new CDropdownToolbar(GetParentFrame(), pMWContext, &rectCaller, ID_ALIGN_POPUP, nInitialID);
  2631.     if( pTB ){
  2632.         pTB->AddButton(IDB_HALIGN_LEFT, ID_ALIGN_LEFT);
  2633.         pTB->AddButton(IDB_HALIGN_CENTER, ID_ALIGN_CENTER);
  2634.         pTB->AddButton(IDB_HALIGN_RIGHT, ID_ALIGN_RIGHT);
  2635.         pTB->Show();
  2636.     }
  2637. }
  2638.  
  2639. void DoAlign(MWContext* pMWContext, ED_Alignment align)
  2640. {
  2641.     ED_ElementType type = EDT_GetCurrentElementType(pMWContext);
  2642.  
  2643.     switch ( type )
  2644.     {
  2645.         case ED_ELEMENT_HRULE:
  2646.         {
  2647.             EDT_HorizRuleData* pData = EDT_GetHorizRuleData(pMWContext);
  2648.             if ( pData ){
  2649.                 pData->align = align;
  2650.                 EDT_SetHorizRuleData(pMWContext, pData);
  2651.             }
  2652.             break;
  2653.         }
  2654.        default: // For Images, Text, or selection, this will do all:
  2655.             EDT_SetParagraphAlign( pMWContext, align );
  2656.             break;
  2657.     }
  2658. }
  2659.  
  2660. void CNetscapeEditView::OnUpdateAlignLeft(CCmdUI* pCmdUI)
  2661. {
  2662.     if( pCmdUI->m_pMenu ){
  2663.         // Get current alignment to set check next to menu items
  2664.         MWContext * pMWContext = GET_MWCONTEXT;
  2665.         if( pMWContext ){
  2666.             ED_ElementType type = EDT_GetCurrentElementType(pMWContext);
  2667.             EDT_HorizRuleData* pData = NULL;
  2668.             ED_Alignment align = ED_ALIGN_LEFT;
  2669.  
  2670.             if( type == ED_ELEMENT_HRULE ){
  2671.                 pData = EDT_GetHorizRuleData(pMWContext);
  2672.                 if ( pData ){
  2673.                     align = pData->align;
  2674.                 }
  2675.             } else {
  2676.                 align = EDT_GetParagraphAlign(pMWContext);
  2677.             }
  2678.             if( align == ED_ALIGN_ABSCENTER ){
  2679.                 align = ED_ALIGN_CENTER;
  2680.             }
  2681.             if( align == ED_ALIGN_DEFAULT ){
  2682.                 align = ED_ALIGN_LEFT;
  2683.             }
  2684.  
  2685.             pCmdUI->SetCheck(align == ED_ALIGN_LEFT ? 1 : 0);
  2686.  
  2687.             // Set check for center and right while we are here:
  2688.             pCmdUI->m_pMenu->CheckMenuItem(ID_ALIGN_CENTER, align == ED_ALIGN_CENTER ? MF_CHECKED : MF_UNCHECKED );
  2689.             pCmdUI->m_pMenu->CheckMenuItem(ID_ALIGN_RIGHT, align == ED_ALIGN_RIGHT ? MF_CHECKED : MF_UNCHECKED );
  2690.         }
  2691.     }
  2692.     pCmdUI->Enable(CAN_INTERACT);
  2693. }
  2694.  
  2695. void CNetscapeEditView::OnAlignLeft()
  2696. {
  2697.         
  2698.     DoAlign(GET_MWCONTEXT, ED_ALIGN_LEFT); 
  2699. }
  2700.  
  2701. void CNetscapeEditView::OnAlignRight()
  2702. {
  2703.     DoAlign(GET_MWCONTEXT, ED_ALIGN_RIGHT); 
  2704. }
  2705. void CNetscapeEditView::OnAlignCenter()
  2706. {                                
  2707.     DoAlign(GET_MWCONTEXT, ED_ALIGN_CENTER); 
  2708. }
  2709.  
  2710. void CNetscapeEditView::OnAlignTableLeft()
  2711. {
  2712.     EDT_SetTableAlign(GET_MWCONTEXT, ED_ALIGN_LEFT);
  2713. }
  2714.  
  2715. void CNetscapeEditView::OnAlignTableRight()
  2716. {
  2717.     EDT_SetTableAlign(GET_MWCONTEXT, ED_ALIGN_RIGHT);
  2718. }
  2719.  
  2720. void CNetscapeEditView::OnAlignTableCenter()
  2721. {
  2722.     EDT_SetTableAlign(GET_MWCONTEXT, ED_ALIGN_CENTER);
  2723. }
  2724.  
  2725. void CNetscapeEditView::OnInsertLineBreak()
  2726. {
  2727.     EDT_InsertBreak(GET_MWCONTEXT, ED_BREAK_NORMAL);
  2728. }
  2729.  
  2730. void CNetscapeEditView::OnInsertBreakLeft()
  2731. {
  2732.     EDT_InsertBreak(GET_MWCONTEXT, ED_BREAK_LEFT);
  2733. }
  2734.  
  2735. void CNetscapeEditView::OnInsertBreakRight()
  2736. {
  2737.     EDT_InsertBreak(GET_MWCONTEXT, ED_BREAK_RIGHT);
  2738. }
  2739.  
  2740. void CNetscapeEditView::OnInsertBreakBoth()
  2741. {
  2742.     EDT_InsertBreak(GET_MWCONTEXT, ED_BREAK_BOTH);
  2743. }
  2744.  
  2745. void CNetscapeEditView::OnUpdateInsertBreak(CCmdUI* pCmdUI)
  2746. {
  2747.     ED_ElementType type = EDT_GetCurrentElementType(GET_MWCONTEXT);
  2748.     pCmdUI->Enable(CAN_INTERACT &&
  2749.                    type == ED_ELEMENT_TEXT || type >= ED_ELEMENT_TABLE);
  2750. }
  2751.  
  2752. void CNetscapeEditView::OnSelectAll()
  2753. {
  2754.     EDT_SelectAll(GET_MWCONTEXT);
  2755.     // Trigger updating paragraph styles combo
  2756.     SetEditChanged();
  2757. }
  2758.  
  2759. void CNetscapeEditView::OnSelectTable()
  2760. {
  2761.     EDT_SelectTable(GET_MWCONTEXT);
  2762.     // Trigger updating paragraph styles combo
  2763.     SetEditChanged();
  2764. }
  2765. void CNetscapeEditView::OnSelectTableRow()
  2766. {
  2767.     EDT_SelectTableElement(GET_MWCONTEXT, 0,0, NULL, ED_HIT_SEL_ROW, FALSE, FALSE );
  2768. }
  2769.  
  2770. void CNetscapeEditView::OnSelectTableColumn()
  2771. {
  2772.     EDT_SelectTableElement(GET_MWCONTEXT, 0,0, NULL, ED_HIT_SEL_COL, FALSE, FALSE );
  2773. }
  2774.  
  2775. void CNetscapeEditView::OnSelectTableCell()
  2776. {
  2777.     EDT_SelectTableElement(GET_MWCONTEXT, 0,0, NULL, ED_HIT_SEL_CELL, FALSE, FALSE );
  2778. }
  2779.  
  2780. void CNetscapeEditView::OnSelectTableAllCells()
  2781. {
  2782.     EDT_SelectTableElement(GET_MWCONTEXT, 0,0, NULL, ED_HIT_SEL_ALL_CELLS, FALSE, FALSE );
  2783. }
  2784.  
  2785. void CNetscapeEditView::OnUpdateInTable(CCmdUI* pCmdUI)
  2786. {
  2787.     pCmdUI->Enable(EDT_IsInsertPointInTable(GET_MWCONTEXT));
  2788. }
  2789.  
  2790. void CNetscapeEditView::OnMergeTableCells()
  2791. {
  2792.     EDT_MergeTableCells(GET_MWCONTEXT);
  2793. }
  2794.  
  2795. void CNetscapeEditView::OnSplitTableCell()
  2796. {
  2797.     EDT_SplitTableCell(GET_MWCONTEXT);
  2798. }
  2799.  
  2800. void CNetscapeEditView::OnUpdateMergeTableCells(CCmdUI* pCmdUI)
  2801. {
  2802.     ED_MergeType MergeType = EDT_GetMergeTableCellsType(GET_MWCONTEXT);
  2803.     if(pCmdUI->m_pMenu)
  2804.     {
  2805.         pCmdUI->m_pMenu->ModifyMenu( ID_MERGE_TABLE_CELLS, MF_BYCOMMAND, 
  2806.                              ID_MERGE_TABLE_CELLS, 
  2807.                              szLoadString(MergeType == ED_MERGE_NEXT_CELL ? IDS_MERGE_NEXT_CELL : IDS_MERGE_SELECTED_CELLS ) );
  2808.     }
  2809.     // Experimental: Allow merging wacky selection sets to see what happens!
  2810.     pCmdUI->Enable(CAN_INTERACT && MergeType != ED_MERGE_NONE);
  2811. }
  2812.  
  2813. void CNetscapeEditView::OnUpdateSplitTableCell(CCmdUI* pCmdUI)
  2814. {
  2815.     pCmdUI->Enable(CAN_INTERACT && EDT_CanSplitTableCell);
  2816. }
  2817.  
  2818. void CNetscapeEditView::OnTableTextConvert()
  2819. {
  2820.     MWContext * pMWContext = GET_MWCONTEXT;
  2821.     if( EDT_IsTableSelected(pMWContext) || EDT_IsInsertPointInTable(pMWContext) )
  2822.     {
  2823.         EDT_ConvertTableToText(pMWContext);
  2824.     } else {
  2825.         //TODO: ADD DIALOG TO GET NUMBER OF COLUMNS
  2826.         // Convert selected text into a table
  2827.         EDT_ConvertTextToTable(pMWContext, 3);
  2828.     }
  2829. }
  2830.  
  2831. void CNetscapeEditView::OnUpdateTableTextConvert(CCmdUI* pCmdUI)
  2832. {
  2833.     // Insert point should ALWAYS be inside table if any cells are selected
  2834.     MWContext * pMWContext = GET_MWCONTEXT;
  2835.     if( EDT_IsTableSelected(pMWContext) || EDT_IsInsertPointInTable(pMWContext) )
  2836.     {
  2837.         pCmdUI->Enable(CAN_INTERACT);
  2838.     } else {
  2839.         pCmdUI->Enable(CAN_INTERACT && EDT_IsSelected(pMWContext) );
  2840.     }
  2841. }
  2842.  
  2843. void CNetscapeEditView::OnUndo()
  2844. {
  2845. #ifdef _IME_COMPOSITION
  2846.     if (m_imebool)
  2847.     {    
  2848.         if (m_pime)
  2849.         {
  2850.     #ifdef XP_WIN32
  2851.             HIMC hIMC;
  2852.             if (hIMC = m_pime->ImmGetContext(this->m_hWnd))
  2853.             {
  2854.                 m_pime->ImmNotifyIME(hIMC,NI_COMPOSITIONSTR,CPS_COMPLETE,NULL);
  2855.                 m_pime->ImmReleaseContext(this->m_hWnd,hIMC);
  2856.             }
  2857.     #else //xp_win16
  2858.             MWContext * pMWContext = GET_MWCONTEXT;
  2859.             if (pMWContext)
  2860.             {
  2861.                 EDT_SetInsertPointToOffset(pMWContext,m_imeoffset+m_imelength,0);
  2862.                 m_pchardata->mask= -1;
  2863.                 CLEARBIT(m_pchardata->values,TF_INLINEINPUT);//we are done!
  2864.                 EDT_SetCharacterDataAtOffset(pMWContext,m_pchardata,m_imeoffset,m_imelength);
  2865.                 m_imelength=0;
  2866.                 OnImeEndComposition();
  2867.             }
  2868.     #endif //XP_WIN32 else xp_win16
  2869.         }
  2870.     }
  2871. #endif //_IME_COMPOSITION
  2872.     if( EDT_GetRedoCommandID(GET_MWCONTEXT, 0 ) != CEDITCOMMAND_ID_NULL ){
  2873.         EDT_Redo(GET_MWCONTEXT);
  2874.     } else if( EDT_GetUndoCommandID(GET_MWCONTEXT, 0 ) != CEDITCOMMAND_ID_NULL ){    
  2875.         EDT_Undo(GET_MWCONTEXT);
  2876.     }
  2877. }
  2878.  
  2879. void CNetscapeEditView::OnUpdateUndo(CCmdUI* pCmdUI)
  2880. {
  2881.     BOOL bRedo = EDT_GetRedoCommandID(GET_MWCONTEXT, 0 ) != CEDITCOMMAND_ID_NULL;
  2882.     // Change strings between "Undo" and "Redo" appropriately
  2883.     if( pCmdUI->m_pMenu ){
  2884.         pCmdUI->m_pMenu->ModifyMenu(ID_EDIT_UNDO, MF_BYCOMMAND | MF_STRING, ID_EDIT_UNDO,
  2885.                                     szLoadString(bRedo ? IDS_REDO : IDS_UNDO) );
  2886.     }    
  2887.     // Disabled only on initial page load.
  2888.     pCmdUI->Enable(CAN_INTERACT && (bRedo || EDT_GetUndoCommandID(GET_MWCONTEXT, 0 ) != CEDITCOMMAND_ID_NULL) );
  2889. }
  2890.  
  2891. void CNetscapeEditView::OnDisplayParagraphMarks()
  2892. {
  2893.     EDT_SetDisplayParagraphMarks(GET_MWCONTEXT, ! EDT_GetDisplayParagraphMarks(GET_MWCONTEXT));
  2894. }
  2895.  
  2896. void CNetscapeEditView::OnUpdateDisplayParagraphMarks(CCmdUI* pCmdUI)
  2897. {
  2898.     CEditToolBarController * pController = 
  2899.         (CEditToolBarController *)GetParentFrame()->SendMessage(WM_TOOLCONTROLLER);
  2900.     if( pController && pCmdUI->m_pMenu ){
  2901.         pCmdUI->m_pMenu->ModifyMenu(ID_EDIT_DISPLAY_PARAGRAPH_MARKS, MF_BYCOMMAND | MF_STRING, 
  2902.                                     CASTUINT(ID_EDIT_DISPLAY_PARAGRAPH_MARKS),
  2903.                                     szLoadString(EDT_GetDisplayParagraphMarks(GET_MWCONTEXT) ?
  2904.                                                  IDS_HIDE_PARA_MARKS : IDS_SHOW_PARA_MARKS) );
  2905.     }
  2906.     pCmdUI->Enable(CAN_INTERACT);
  2907. }
  2908.  
  2909. void CNetscapeEditView::OnInsertObjectPopup()
  2910. {
  2911.     MWContext * pMWContext = GET_MWCONTEXT;
  2912.     if( ! pMWContext ){
  2913.         return;
  2914.     }
  2915.     RECT rectCaller = {0,0, 0, 0};
  2916.     CEditToolBarController * pController = 
  2917.         (CEditToolBarController *)GetParentFrame()->SendMessage(WM_TOOLCONTROLLER);
  2918.     if (pController)
  2919.     {
  2920.         // This ALWAYS gets the CharacterToolbar
  2921.         CNSToolbar2 *pCNSToolbar = pController->GetCNSToolbar();
  2922.         if( !pCNSToolbar || !pCNSToolbar->GetButtonRect(ID_INSERT_POPUP, &rectCaller) )
  2923.         {
  2924.             // If we didn't find the button on the Charater toolbar
  2925.             //    (used in just the Message Composer), then we are in
  2926.             //    Composer window and button is on the Composition toolbar
  2927.             CGenericFrame *pParent = (CGenericFrame*)GetParentFrame();
  2928.             LPNSTOOLBAR pIToolBar;
  2929.             pParent->GetChrome()->QueryInterface( IID_INSToolBar, (LPVOID *) &pIToolBar );
  2930.             if (pIToolBar)
  2931.             {
  2932.                 pIToolBar->GetButtonRect(ID_INSERT_POPUP, &rectCaller);
  2933.                    pIToolBar->Release();
  2934.             }
  2935.         }
  2936.  
  2937.     }
  2938.  
  2939.     // Build dropdown toolbar for insert object buttons
  2940.     //   CommandID is sent to parent frame when pressed
  2941.     pTB = NULL;
  2942.     pTB = new CDropdownToolbar(GetParentFrame(), pMWContext, &rectCaller, ID_INSERT_POPUP, 0);
  2943.     if( pTB ){
  2944.         pTB->AddButton(IDB_INSERT_LINK, ID_MAKE_LINK);
  2945.         pTB->AddButton(IDB_INSERT_TARGET, ID_INSERT_TARGET);
  2946.         pTB->AddButton(IDB_INSERT_IMAGE, ID_INSERT_IMAGE);
  2947.         pTB->AddButton(IDB_INSERT_HRULE, ID_INSERT_HRULE);
  2948.         pTB->AddButton(IDB_INSERT_TABLE, ID_INSERT_TABLE);
  2949.         pTB->Show();
  2950.     }
  2951. }
  2952.  
  2953.  
  2954. // InsertTable
  2955.  
  2956. void CNetscapeEditView::OnInsertTable()
  2957. {
  2958.     MWContext * pMWContext = GET_MWCONTEXT;
  2959.     if( pMWContext ){
  2960.         // Unselect so we insert after after the object
  2961.         if( NonLinkObjectIsSelected(pMWContext) )
  2962.             EDT_ClearSelection(pMWContext);
  2963.         // Insert a default table
  2964.         EDT_TableData *pTableData = EDT_NewTableData();
  2965.         if( pTableData )
  2966.         {
  2967.             EDT_InsertTable(pMWContext, pTableData);
  2968.             EDT_FreeTableData(pTableData);
  2969.             OnTableProperties(0);
  2970.         }
  2971.     }
  2972. }
  2973.  
  2974. void CNetscapeEditView::OnInsertTableOrTableProps()
  2975. {
  2976.     MWContext * pMWContext = GET_MWCONTEXT;
  2977.     if( pMWContext )
  2978.     {
  2979.         // If inside a table, toolbar button should
  2980.         //  show properties of that table
  2981.         if( EDT_IsInsertPointInTable(pMWContext) )
  2982.         {
  2983.             // Get last-selected table region type so 
  2984.             //  we can show region-specific properties item,
  2985.             //  even though we will also show character and other property menu items above it
  2986.             ED_HitType iTableHit = EDT_GetSelectedTableElement(pMWContext, NULL);
  2987.             // Default is Table properties - first page
  2988.             int iStart = 0;
  2989.             if( iTableHit == ED_HIT_SEL_ROW ||
  2990.                 iTableHit == ED_HIT_SEL_COL ||
  2991.                 iTableHit == ED_HIT_SEL_CELL )
  2992.             {
  2993.                 iStart = 1;
  2994.             }
  2995.             OnTableProperties(iStart);
  2996.         } else {
  2997.             // Not in table -- insert a new one
  2998.             OnInsertTable();
  2999.         }
  3000.     }
  3001. }
  3002.  
  3003. void CNetscapeEditView::OnUpdateInsertTable(CCmdUI* pCmdUI)
  3004. {
  3005.     pCmdUI->Enable(CAN_INTERACT && !EDT_IsJavaScript(GET_MWCONTEXT));
  3006. }
  3007.  
  3008. // DeleteTable
  3009.  
  3010. void CNetscapeEditView::OnDeleteTable()
  3011. {
  3012.     EDT_DeleteTable(GET_MWCONTEXT);
  3013. }
  3014.  
  3015. // InsertTableRow
  3016.  
  3017. void CNetscapeEditView::OnInsertTableRow()
  3018. {
  3019.     EDT_TableRowData* pData = EDT_GetTableRowData( GET_MWCONTEXT );
  3020.     if( pData){
  3021.         SetCursor(theApp.LoadStandardCursor(IDC_WAIT));
  3022.         // The 0 will cause us to use number of selected rows,
  3023.         //  or just 1 if there's none or 1 selected cell
  3024.         EDT_InsertTableRows(GET_MWCONTEXT, pData, TRUE, 0);
  3025.         EDT_FreeTableRowData(pData);
  3026.         SetCursor(theApp.LoadStandardCursor(IDC_ARROW));
  3027.     }
  3028. }
  3029.  
  3030. void CNetscapeEditView::OnInsertTableRowAbove()
  3031. {
  3032.     EDT_TableRowData* pData = EDT_GetTableRowData( GET_MWCONTEXT );
  3033.     if( pData){
  3034.         SetCursor(theApp.LoadStandardCursor(IDC_WAIT));
  3035.         EDT_InsertTableRows(GET_MWCONTEXT, pData, FALSE, 0);
  3036.         EDT_FreeTableRowData(pData);
  3037.         SetCursor(theApp.LoadStandardCursor(IDC_ARROW));
  3038.     }
  3039. }
  3040.  
  3041. void CNetscapeEditView::OnUpdateInsertTableRow(CCmdUI* pCmdUI)
  3042. {
  3043.     // ALERT! BOGUS MFC BEHAVIOR
  3044.     // We should only test for menu popup,
  3045.     //  but pCmdUI->m_pMenu is NULL when called from WINCORE.CPP:
  3046.     //    BOOL CWnd::OnCommand(WPARAM wParam, LPARAM lParam)...
  3047.     //              OnCmdMsg(nID, CN_UPDATE_COMMAND_UI, &state, NULL);
  3048.     // Why, I don't know! But result is command doesn't happen and you get
  3049.     //  message: Warning: not executing disabled command <ID>
  3050.  
  3051.     if( /*pCmdUI->m_pMenu && */ EDT_IsInsertPointInTableRow(GET_MWCONTEXT) ){
  3052.         EDT_TableData* pData = EDT_GetTableData( GET_MWCONTEXT );
  3053.         if(pData){
  3054.             pCmdUI->Enable(pData->iRows < MAX_TABLE_ROWS);
  3055.             EDT_FreeTableData(pData);
  3056.             return;
  3057.         }
  3058.     }
  3059.     pCmdUI->Enable(FALSE);
  3060. }
  3061.  
  3062. // DeleteTableRow
  3063.  
  3064. void CNetscapeEditView::OnDeleteTableRow()
  3065. {
  3066.     EDT_DeleteTableRows(GET_MWCONTEXT, 1);
  3067. }
  3068.  
  3069. void CNetscapeEditView::OnUpdateInTableRow(CCmdUI* pCmdUI)
  3070. {
  3071.     pCmdUI->Enable(EDT_IsInsertPointInTableRow(GET_MWCONTEXT));
  3072. }
  3073.  
  3074. // InsertTableCaption
  3075.  
  3076. void CNetscapeEditView::OnInsertTableCaption()
  3077. {
  3078.     EDT_TableCaptionData* pData = EDT_NewTableCaptionData();
  3079.     if( pData ){
  3080.         EDT_InsertTableCaption(GET_MWCONTEXT, pData);
  3081.         EDT_FreeTableCaptionData(pData);
  3082.     }
  3083. }
  3084.  
  3085. void CNetscapeEditView::OnUpdateInsertTableCaption(CCmdUI* pCmdUI)
  3086. {
  3087.     pCmdUI->Enable(EDT_IsInsertPointInTable(GET_MWCONTEXT));
  3088. }
  3089.  
  3090. // DeleteTableCaption
  3091.  
  3092. void CNetscapeEditView::OnDeleteTableCaption()
  3093. {
  3094.     EDT_DeleteTableCaption(GET_MWCONTEXT);
  3095. }
  3096.  
  3097. void CNetscapeEditView::OnUpdateInTableCaption(CCmdUI* pCmdUI)
  3098. {
  3099.     pCmdUI->Enable(EDT_IsInsertPointInTableCaption(GET_MWCONTEXT));
  3100. }
  3101.  
  3102. // InsertTableColumn
  3103.  
  3104. void CNetscapeEditView::OnInsertTableColumn()
  3105. {
  3106.     EDT_TableCellData* pData = EDT_NewTableCellData();
  3107.     if( pData ){
  3108.         SetCursor(theApp.LoadStandardCursor(IDC_WAIT));
  3109.         // The 0 will cause us to use number of selected columns,
  3110.         //  or just 1 if there's none or 1 selected cell
  3111.         EDT_InsertTableColumns(GET_MWCONTEXT, pData, TRUE, 0);
  3112.         EDT_FreeTableCellData(pData);
  3113.         SetCursor(theApp.LoadStandardCursor(IDC_ARROW));
  3114.     }
  3115. }
  3116.  
  3117. void CNetscapeEditView::OnInsertTableColumnBefore()
  3118. {
  3119.     EDT_TableCellData* pData = EDT_NewTableCellData();
  3120.     if( pData ){
  3121.         SetCursor(theApp.LoadStandardCursor(IDC_WAIT));
  3122.         EDT_InsertTableColumns(GET_MWCONTEXT, pData, FALSE, 0);
  3123.         EDT_FreeTableCellData(pData);
  3124.         SetCursor(theApp.LoadStandardCursor(IDC_ARROW));
  3125.     }
  3126. }
  3127.  
  3128. void CNetscapeEditView::OnUpdateInsertTableColumn(CCmdUI* pCmdUI)
  3129. {
  3130.     if( EDT_IsInsertPointInTableRow(GET_MWCONTEXT) )
  3131.     {
  3132.         EDT_TableData* pData = EDT_GetTableData( GET_MWCONTEXT );
  3133.         if(pData){
  3134.             pCmdUI->Enable(pData->iColumns < MAX_TABLE_COLUMNS);
  3135.             EDT_FreeTableData(pData);
  3136.             return;
  3137.         }
  3138.     }
  3139.     pCmdUI->Enable(FALSE);
  3140. }
  3141.  
  3142. // DeleteTableColumn
  3143.  
  3144. void CNetscapeEditView::OnDeleteTableColumn()
  3145. {
  3146.     EDT_DeleteTableColumns(GET_MWCONTEXT, 1);
  3147. }
  3148.  
  3149. void CNetscapeEditView::OnUpdateInTableColumn(CCmdUI* pCmdUI)
  3150. {
  3151.     pCmdUI->Enable(EDT_IsInsertPointInTableRow(GET_MWCONTEXT));
  3152. }
  3153.  
  3154. // InsertTableCell
  3155.  
  3156. void CNetscapeEditView::OnInsertTableCell()
  3157. {
  3158.     EDT_TableCellData* pData = EDT_NewTableCellData();
  3159.     if( pData ){
  3160.         SetCursor(theApp.LoadStandardCursor(IDC_WAIT));
  3161.         EDT_InsertTableCells(GET_MWCONTEXT, pData, TRUE, 1);
  3162.         EDT_FreeTableCellData(pData);
  3163.         SetCursor(theApp.LoadStandardCursor(IDC_ARROW));
  3164.     }
  3165. }
  3166.  
  3167. void CNetscapeEditView::OnInsertTableCellBefore()
  3168. {
  3169.     EDT_TableCellData* pData = EDT_NewTableCellData();
  3170.     if( pData ){
  3171.         SetCursor(theApp.LoadStandardCursor(IDC_WAIT));
  3172.         EDT_InsertTableCells(GET_MWCONTEXT, pData, FALSE, 1);
  3173.         EDT_FreeTableCellData(pData);
  3174.         SetCursor(theApp.LoadStandardCursor(IDC_ARROW));
  3175.     }
  3176. }
  3177.  
  3178. void CNetscapeEditView::OnUpdateInsertTableCell(CCmdUI* pCmdUI)
  3179. {
  3180.     if( EDT_IsInsertPointInTableRow(GET_MWCONTEXT) )
  3181.     {
  3182.         EDT_TableData* pData = EDT_GetTableData( GET_MWCONTEXT );
  3183.         if(pData){
  3184.             pCmdUI->Enable(pData->iRows < MAX_TABLE_ROWS && 
  3185.                            pData->iColumns < MAX_TABLE_COLUMNS);
  3186.             EDT_FreeTableData(pData);
  3187.             return;
  3188.         }
  3189.     }
  3190.     pCmdUI->Enable(FALSE);
  3191. }
  3192.  
  3193. // DeleteTableCell
  3194.  
  3195. void CNetscapeEditView::OnDeleteTableCell()
  3196. {
  3197.     EDT_DeleteTableCells(GET_MWCONTEXT, 1);
  3198. }
  3199.  
  3200. void CNetscapeEditView::OnUpdateInTableCell(CCmdUI* pCmdUI)
  3201. {
  3202.     pCmdUI->Enable(EDT_IsInsertPointInTableRow(GET_MWCONTEXT));
  3203. }
  3204.  
  3205. // ToggleTableBorder
  3206.  
  3207. void CNetscapeEditView::OnToggleTableBorder()
  3208. {
  3209.     Bool bInTable = EDT_IsInsertPointInTable(GET_MWCONTEXT);
  3210.     Bool bCheck = FALSE;
  3211.     if ( bInTable ) {
  3212.         EDT_TableData* pData = EDT_GetTableData(GET_MWCONTEXT);
  3213.         if ( pData ) {
  3214.             bCheck = pData->iBorderWidth > 0;
  3215.             intn iNewBorder = 1;
  3216.             if ( bCheck ) {
  3217.                 iNewBorder = 0;
  3218.             }
  3219.             pData->iBorderWidth = iNewBorder;
  3220.             EDT_SetTableData(GET_MWCONTEXT, pData);
  3221.             EDT_FreeTableData(pData);
  3222.         }
  3223.     }
  3224. }
  3225.  
  3226. void CNetscapeEditView::OnUpdateToggleTableBorder(CCmdUI* pCmdUI)
  3227. {
  3228.     Bool bInTable = EDT_IsInsertPointInTable(GET_MWCONTEXT);
  3229.     Bool bCheck = FALSE;
  3230.     if ( bInTable ) {
  3231.         EDT_TableData* pData = EDT_GetTableData(GET_MWCONTEXT);
  3232.         if ( pData ) {
  3233.             bCheck = pData->iBorderWidth > 0;
  3234.             EDT_FreeTableData(pData);
  3235.         }
  3236.     }
  3237.     pCmdUI->SetCheck(bCheck );
  3238.     pCmdUI->Enable(bInTable);
  3239. }
  3240.  
  3241. void CNetscapeEditView::OnToggleHeaderCell()
  3242. {
  3243.     Bool bInTableCell = EDT_IsInsertPointInTableCell(GET_MWCONTEXT);
  3244.     Bool bCheck = FALSE;
  3245.     if ( bInTableCell ) {
  3246.         EDT_TableCellData* pData = EDT_GetTableCellData(GET_MWCONTEXT);
  3247.         if ( pData ) {
  3248.             pData->bHeader = ! pData->bHeader;
  3249.             EDT_SetTableCellData(GET_MWCONTEXT, pData);
  3250.             EDT_FreeTableCellData(pData);
  3251.         }
  3252.     }
  3253. }
  3254.  
  3255. void CNetscapeEditView::OnUpdateToggleHeaderCell(CCmdUI* pCmdUI)
  3256. {
  3257.     Bool bInTableCell = EDT_IsInsertPointInTableCell(GET_MWCONTEXT);
  3258.     Bool bCheck = FALSE;
  3259.     if ( bInTableCell ) {
  3260.         EDT_TableCellData* pData = EDT_GetTableCellData(GET_MWCONTEXT);
  3261.         if ( pData ) {
  3262.             bCheck = pData->bHeader;
  3263.             EDT_FreeTableCellData(pData);
  3264.         }
  3265.     }
  3266.     pCmdUI->SetCheck(bCheck );
  3267.     pCmdUI->Enable(bInTableCell);
  3268. }
  3269.  
  3270. // Table Properties
  3271. void CNetscapeEditView::OnPropsTable()
  3272. {
  3273.     OnTableProperties(0);
  3274. }
  3275.  
  3276. void CNetscapeEditView::OnPropsTableRow()
  3277. {
  3278.     OnTableProperties(1);
  3279. }
  3280.  
  3281. void CNetscapeEditView::OnPropsTableColumn()
  3282. {
  3283.     OnTableProperties(0);
  3284. }
  3285.  
  3286. void CNetscapeEditView::OnPropsTableCell()
  3287. {
  3288.     OnTableProperties(1);
  3289. }
  3290.  
  3291. void CNetscapeEditView::OnTableProperties(int iStartPage)
  3292. {
  3293.     MWContext * pMWContext = GET_MWCONTEXT;
  3294.     if (pMWContext == NULL || !EDT_IS_EDITOR(pMWContext)) {
  3295.         return;
  3296.     }
  3297.     int iPageMax = 0;
  3298.     EDT_TableData * pTableData = EDT_GetTableData(pMWContext);
  3299.     if( !pTableData )
  3300.         return;
  3301.  
  3302.     // Get the cell data
  3303.     EDT_TableCellData* pCellData = EDT_GetTableCellData(pMWContext);
  3304.  
  3305.     CNetscapePropertySheet PropsDlg( szLoadString(IDS_PROPS_TABLE_CAPTION),
  3306.                                     GET_DLG_PARENT(this), 0, pMWContext, TRUE); // Use the Apply Button
  3307.  
  3308.     // This will change resource hInstance to EditorXX.dll (in its constructor)
  3309.     // We pass this into our property page, which resets back to EXE's resources later
  3310.     CEditorResourceSwitcher ResourceSwitcher;
  3311.     
  3312.     CTablePage * pTablePage = new CTablePage(this, pMWContext, &ResourceSwitcher, pTableData);
  3313.     CTableCellPage * pCellPage = NULL;
  3314.  
  3315.     PropsDlg.AddPage(pTablePage);
  3316.  
  3317.     if( pCellData )
  3318.     {
  3319.         // Change the tab text corresponding to selected cells type
  3320.         // NOTE: These string must be in EDITORxx.DLL resources
  3321.         //        because they are loaded during dialog construction
  3322.         UINT nIDCaption = 0; // Default is single "Cell" label
  3323.         if( pCellData->iSelectedCount > 1 )
  3324.         {
  3325.             switch( pCellData->iSelectionType )
  3326.             {
  3327.                 case ED_HIT_SEL_COL:
  3328.                     nIDCaption = IDS_SELECTED_COLUMN_CAPTION;
  3329.                     break;
  3330.                 case ED_HIT_SEL_ROW:
  3331.                     nIDCaption = IDS_SELECTED_ROW_CAPTION;
  3332.                     break;
  3333.                 default:
  3334.                    nIDCaption = IDS_SELECTED_CELLS_CAPTION;
  3335.                    break;
  3336.             }
  3337.         }
  3338.         
  3339.         pCellPage = new CTableCellPage(this, pMWContext, &ResourceSwitcher, pCellData, nIDCaption);
  3340.         PropsDlg.AddPage(pCellPage);
  3341.         iPageMax++;
  3342.     }
  3343.  
  3344.     int32 iPage = max( iPageMax, iStartPage );
  3345.     PropsDlg.SetCurrentPage(min(CASTINT(iStartPage), iPageMax));
  3346.  
  3347.     if( pCellData )
  3348.     {
  3349.         // Note: We used to do  EDT_BeginBatchChanges/EDT_EndBatchChanges around this
  3350.         // But that causes us to loose undo buffer even if user cancels from properties
  3351.  
  3352.         // This selects the current cell and changes other
  3353.         //  cells selected to the "special" selection style
  3354.         //  so user can tell the focus cell (= current) from
  3355.         //  other selected cells
  3356.         EDT_StartSpecialCellSelection(pMWContext, pCellData);
  3357.         PropsDlg.DoModal();
  3358.         EDT_ClearSpecialCellSelection(pMWContext);
  3359.     }
  3360.  
  3361.     EDT_FreeTableData(pTableData);
  3362.  
  3363.     if( pCellData ) EDT_FreeTableCellData(pCellData);
  3364.     
  3365.     if( pCellPage ) delete pCellPage;
  3366.     delete pTablePage;
  3367. }
  3368.  
  3369. void CNetscapeEditView::OnUpdateEditFindincurrent(CCmdUI* pCmdUI)
  3370. {
  3371.     if (!CAN_INTERACT)
  3372.         pCmdUI->Enable(FALSE);
  3373.     else
  3374.         CGenericView::OnUpdateEditFindincurrent(pCmdUI);
  3375. }
  3376.  
  3377. void CNetscapeEditView::OnUpdateEditFindAgain(CCmdUI* pCmdUI)
  3378. {
  3379.     if (!CAN_INTERACT)
  3380.         pCmdUI->Enable(FALSE);
  3381.     else
  3382.         CGenericView::OnUpdateEditFindAgain(pCmdUI);
  3383. }
  3384.  
  3385. void CNetscapeEditView::OnUpdateFileDocinfo(CCmdUI* pCmdUI) 
  3386. {
  3387.     if (!CAN_INTERACT)
  3388.         pCmdUI->Enable(FALSE);
  3389.     else
  3390.         CGenericView::OnUpdateFileDocinfo(pCmdUI);
  3391. }
  3392.  
  3393.  
  3394. /////////////////////////ADDED here from edview.cpp due to compiler running out of keys///////////
  3395. //MFJ10-8-97 mjudge
  3396.  
  3397. #ifdef _IME_COMPOSITION
  3398.  
  3399. #ifdef XP_WIN32
  3400.  
  3401. BOOL
  3402. CNetscapeEditView::ImeSetFont(HWND p_hwnd,LOGFONT *p_plogfont)
  3403. {
  3404.     if (!initializeIME())
  3405.         return FALSE;
  3406.     HIMC hIMC;
  3407.     if ((hIMC = m_pime->ImmGetContext(this->m_hWnd)) == NULL)
  3408.         return FALSE;
  3409.     return m_pime->ImmSetCompositionFont(hIMC,p_plogfont);
  3410. }
  3411.  
  3412.  
  3413. BOOL
  3414. CNetscapeEditView::initializeIME()
  3415. {
  3416.     if (!m_pime)
  3417.         m_pime=m_resourcedll.CreateImeDll();
  3418.     if (!m_pime)
  3419.     {
  3420.         assert(FALSE);
  3421.         return FALSE;
  3422.     }
  3423.     HIMC hIMC;
  3424.     if ((hIMC = m_pime->ImmGetContext(this->m_hWnd)) == NULL)
  3425.         return FALSE;
  3426.        CPoint point= GetCaretPos();
  3427.     CANDIDATEFORM form;
  3428.     form.dwIndex=0;
  3429.     form.dwStyle=CFS_CANDIDATEPOS;
  3430.     form.ptCurrentPos.x=point.x;
  3431.     form.ptCurrentPos.y=point.y;
  3432.     VERIFY(m_pime->ImmSetCandidateWindow(hIMC,&form));
  3433.  
  3434.     m_pime->ImmReleaseContext(this->m_hWnd,hIMC);
  3435.  
  3436.     CWinCX    * pContext = GetContext();
  3437.     MWContext * pMWContext = pContext->GetContext();
  3438.  
  3439.     //one more thing, if previous selection,  we must delete it.
  3440.     if (EDT_IsSelected(pMWContext))
  3441.     {
  3442.         EDT_DeleteChar(pMWContext);//message boxes here would screw up IME
  3443.         //do nothing with error, errors here do not concern us.  probably just crossed a table boundary.            
  3444.     }
  3445.     m_imeoffset=EDT_GetInsertPointOffset(pMWContext);//used for calls to backend
  3446.     m_imelength=0;
  3447.     m_imebool=TRUE;
  3448.     XP_FREEIF(m_pchardata);
  3449.     m_pchardata=EDT_GetCharacterData(pMWContext);
  3450.     m_oldstring="";
  3451.     return TRUE;
  3452. }
  3453.  
  3454. LRESULT CNetscapeEditView::OnWmeImeStartComposition(WPARAM wparam,LPARAM lparam)
  3455. {
  3456.     if (!initializeIME())
  3457.     {
  3458.         assert(FALSE);
  3459.         return DefWindowProc(WM_IME_STARTCOMPOSITION,wparam,lparam);
  3460.     }
  3461.     return TRUE; //DefWindowProc(WM_IME_STARTCOMPOSITION,wparam,lparam);
  3462. }
  3463.  
  3464.  
  3465.  
  3466. LRESULT CNetscapeEditView::OnWmeImeKeyDown(WPARAM wparam,LPARAM lparam)
  3467. {
  3468.     if (m_pime&& (0x19==wparam))
  3469.     {
  3470.         //open ime, remember state in imestate
  3471.         //set open status to Chinese characters
  3472.         HIMC hIMC;
  3473.         HKL hKL=GetKeyboardLayout(0);    
  3474.         //DWORD fdwConversion;
  3475.         //DWORD fdwSentence;
  3476.         MWContext * pMWContext = GET_MWCONTEXT;
  3477.         if (!pMWContext)
  3478.             return DefWindowProc(WM_IME_STARTCOMPOSITION,wparam,lparam);
  3479.  
  3480.  
  3481.         if (hIMC = m_pime->ImmGetContext(this->m_hWnd)){
  3482.  
  3483.             UINT t_imeoffset=EDT_GetInsertPointOffset(pMWContext);//used for calls to backend
  3484.             EDT_NextChar(pMWContext,TRUE);//TRUE to select character
  3485.             char *text;
  3486.             int32 textLen, hLen;
  3487.             XP_HUGE_CHAR_PTR htmlData = 0;
  3488.             SetCursor(theApp.LoadStandardCursor(IDC_WAIT));
  3489.             if(( EDT_COP_OK != (CASTINT(EDT_CopySelection(pMWContext, &text, &textLen, &htmlData, &hLen))) ))
  3490.                 return DefWindowProc(WM_IME_STARTCOMPOSITION,wparam,lparam);
  3491.             if (!text||!strlen(text))
  3492.                 return DefWindowProc(WM_IME_STARTCOMPOSITION,wparam,lparam);
  3493.             if (m_pime->ImeEscape(hKL,hIMC,IME_ESC_HANJA_MODE,text))
  3494.             {
  3495.                 if (!initializeIME())
  3496.                     return DefWindowProc(WM_IME_STARTCOMPOSITION,wparam,lparam);
  3497.                 m_imelength=strlen(text);
  3498.                 EDT_SetInsertPointToOffset(pMWContext,m_imeoffset,0);
  3499.             }
  3500.             XP_FREEIF(text);
  3501.             m_pime->ImmReleaseContext(this->m_hWnd,hIMC);
  3502.         }
  3503.         return DefWindowProc(WM_IME_STARTCOMPOSITION,wparam,lparam);
  3504.     }
  3505.     else
  3506.         return DefWindowProc(WM_IME_STARTCOMPOSITION,wparam,lparam);
  3507. }
  3508.  
  3509.  
  3510.  
  3511. LRESULT CNetscapeEditView::OnWmeImeEndComposition(WPARAM wparam,LPARAM lparam)
  3512. {
  3513.     if (!m_pime)
  3514.     {
  3515.         assert(FALSE);
  3516.         return DefWindowProc(WM_IME_STARTCOMPOSITION,wparam,lparam);
  3517.     }
  3518.     return TRUE;//DefWindowProc(WM_IME_ENDCOMPOSITION,wparam,lparam);
  3519. }
  3520.  
  3521.  
  3522. LRESULT CNetscapeEditView::OnWmeImeComposition(WPARAM wparam,LPARAM lparam)
  3523. {
  3524.     if (!m_imebool)
  3525.         if (!initializeIME())
  3526.     {
  3527.         assert(FALSE);
  3528.         return DefWindowProc(WM_IME_STARTCOMPOSITION,wparam,lparam);
  3529.     }
  3530.     HIMC hIMC;
  3531.     char *szComp=NULL;
  3532.     char *szResultStr=NULL;
  3533.  
  3534.     BYTE *attributearray=NULL;
  3535.     DWORD dwAttrSize=0;
  3536.     DWORD dwResultSize=0;
  3537.     DWORD dwRead=0;
  3538.     DWORD dwSize=0;
  3539.     WORD cursorPos;
  3540.     WORD deltaPos;
  3541.     BOOL cursorPosMoved=FALSE;
  3542.  
  3543.     if ((hIMC = m_pime->ImmGetContext(this->m_hWnd)) == NULL)
  3544.         return FALSE;
  3545.     if ( lparam & GCS_RESULTSTR )
  3546.     {
  3547.         dwResultSize=m_pime->ImmGetCompositionString( hIMC, GCS_RESULTSTR, NULL, 0 );
  3548.         szResultStr=new char[dwResultSize+1];
  3549.         dwResultSize=m_pime->ImmGetCompositionString( hIMC, GCS_RESULTSTR, szResultStr, dwResultSize );
  3550.     }
  3551.     if ( lparam & GCS_COMPSTR )
  3552.     {
  3553.          dwSize=m_pime->ImmGetCompositionString(hIMC,GCS_COMPSTR, NULL, 0);
  3554.          szComp=new char[dwSize+1];
  3555.          dwSize=m_pime->ImmGetCompositionString(hIMC,GCS_COMPSTR, szComp, dwSize);
  3556.     }
  3557.     if ( lparam & GCS_DELTASTART)
  3558.     {
  3559.          deltaPos=LOWORD((DWORD) m_pime->ImmGetCompositionString(hIMC,GCS_DELTASTART, NULL, 0));
  3560.     }
  3561.     if (lparam & GCS_CURSORPOS)
  3562.     {
  3563.          cursorPos=LOWORD((DWORD) m_pime->ImmGetCompositionString(hIMC,GCS_CURSORPOS, NULL, 0));
  3564.          cursorPosMoved= cursorPos!=m_imeoldcursorpos;
  3565.          m_imeoldcursorpos=cursorPos;
  3566.     }
  3567.     if (lparam & GCS_COMPATTR)
  3568.     {
  3569.         dwAttrSize = LOWORD((DWORD) m_pime->ImmGetCompositionString(hIMC, GCS_COMPATTR,NULL, 0));
  3570.         attributearray = new BYTE[dwAttrSize+1];
  3571.         dwAttrSize = LOWORD((DWORD) m_pime->ImmGetCompositionString(hIMC, GCS_COMPATTR,attributearray, dwAttrSize));
  3572.     }
  3573.     
  3574.     if (lparam==0)
  3575.         dwSize=0;
  3576.     m_pime->ImmReleaseContext(this->m_hWnd,hIMC);//done with context
  3577.  
  3578.     if (szComp)
  3579.         szComp[dwSize]=(char)NULL;
  3580.     if (szResultStr)
  3581.         szResultStr[dwResultSize]=(char)NULL;
  3582.  
  3583.     CWinCX    * pContext = GetContext();
  3584.     MWContext * pMWContext = pContext->GetContext();
  3585.     INTL_CharSetInfo csi = LO_GetDocumentCharacterSetInfo(pMWContext);
  3586.     int16 win_csid = INTL_GetCSIWinCSID(csi);
  3587.     unsigned char *t_unicodestring=NULL;
  3588.  
  3589.     if (dwResultSize)
  3590.     {
  3591.         EDT_SetInsertPointToOffset(pMWContext,m_imeoffset,m_imelength);
  3592.         m_pchardata->mask= -1;//TF_INLINEINPUT;
  3593.         CLEARBIT(m_pchardata->values,TF_INLINEINPUT);
  3594.  
  3595.         if ((win_csid==CS_UTF8)||(win_csid==CS_UTF7))
  3596.         {
  3597.             t_unicodestring= INTL_ConvertLineWithoutAutoDetect(m_csid,win_csid,(unsigned char *)szResultStr,strlen(szResultStr));
  3598.             EDT_InsertText( pMWContext, (char *)t_unicodestring ); 
  3599.             m_imelength= strlen((char *)t_unicodestring);
  3600.             XP_FREEIF(t_unicodestring);
  3601.         }
  3602.         else
  3603.         {
  3604.             EDT_InsertText( pMWContext, szResultStr ); 
  3605.             m_pchardata->mask= -1;//TF_INLINEINPUT;
  3606.             m_imelength= strlen(szResultStr);
  3607.         }
  3608.         EDT_SetCharacterDataAtOffset(pMWContext,m_pchardata,m_imeoffset,m_imelength);
  3609.         m_imeoffset+=m_imelength;
  3610.         m_imelength=0;//no selections. everything is commited
  3611.         m_oldstring="";
  3612.         m_imebool=FALSE;
  3613.         m_imeoldcursorpos= (DWORD)-1;
  3614.     }
  3615.     if (dwSize)
  3616.     {
  3617.         int t_szcompstrlen;
  3618.         int t_difference=-1;
  3619.         char *t_pchar;
  3620.         if ((win_csid==CS_UTF8)||(win_csid==CS_UTF7))
  3621.         {
  3622.             t_unicodestring= INTL_ConvertLineWithoutAutoDetect(m_csid,win_csid,(unsigned char *)szComp,strlen(szComp));
  3623.             t_szcompstrlen=strlen((char *)t_unicodestring);
  3624.             t_pchar=(char *)t_unicodestring;
  3625.  
  3626.             if (lparam & GCS_DELTASTART)
  3627.             {
  3628.                 int32 charCount = INTL_TextByteCountToCharLen(m_csid, (unsigned char *)szComp, deltaPos);
  3629.                 t_difference = (WORD)INTL_TextCharLenToByteCount(win_csid, t_unicodestring, charCount);
  3630.             }
  3631.             else
  3632.             {        
  3633.                 t_difference=findDifference(m_oldstring,(char *)t_unicodestring,pMWContext); //different strings?
  3634.                 if (t_difference!= -1)
  3635.                 {
  3636.                     int32 charCount = INTL_TextByteCountToCharLen(m_csid, (unsigned char *)szComp, t_difference);
  3637.                     t_difference = (WORD)INTL_TextCharLenToByteCount(win_csid, t_unicodestring, charCount);
  3638.                 }
  3639.             }
  3640.  
  3641.             if (lparam & GCS_CURSORPOS)
  3642.             {
  3643.                 if(cursorPos == strlen(szComp))
  3644.                 {
  3645.                     cursorPos = t_szcompstrlen;
  3646.                 }
  3647.                 else
  3648.                 {
  3649.                     int32 charCount = INTL_TextByteCountToCharLen(m_csid, (unsigned char *)szComp, cursorPos);
  3650.                     cursorPos = (WORD)INTL_TextCharLenToByteCount(win_csid, t_unicodestring, charCount);
  3651.                 }
  3652.             }
  3653.         }
  3654.         else
  3655.         {
  3656.             t_szcompstrlen=strlen(szComp);
  3657.             t_pchar=szComp;
  3658.             if (lparam & GCS_DELTASTART)
  3659.                 t_difference = deltaPos;
  3660.             else
  3661.                 t_difference=findDifference(m_oldstring,t_pchar,pMWContext); //different strings?
  3662.         }
  3663.         if ((t_szcompstrlen==t_difference)&&(t_difference==m_oldstring.GetLength()))
  3664.             t_difference= -1; //hack to prevent invalid DELTAPOS from causing me to delete characters.
  3665.         if ((t_difference!= -1)||!m_oldstring.GetLength())
  3666.         {
  3667.             if (t_difference== -1)
  3668.                 t_difference=0;
  3669.             if (t_difference==t_szcompstrlen) //someone hit backspace!
  3670.             {
  3671.                 EDT_SetInsertPointToOffset(pMWContext,m_imeoffset+t_difference,m_imelength-t_difference);
  3672.                 EDT_DeleteChar(pMWContext); //do nothing with error, errors here do not concern us.  probably just crossed a table boundary.            
  3673.                 m_imelength-=m_imelength-t_difference;
  3674.                 m_oldstring=t_pchar;//autocopy from overloaded =
  3675.             }
  3676.             else //if (t_difference>=m_imelength)
  3677.             {
  3678.                 if ((t_difference>=m_imelength)&&(m_imelength != (ED_BufferOffset)strlen(t_pchar)))
  3679.                     EDT_SetInsertPointToOffset(pMWContext,m_imeoffset+m_imelength,0);
  3680.                 else
  3681.                     EDT_SetInsertPointToOffset(pMWContext,m_imeoffset+t_difference,m_imelength-t_difference);
  3682.                 m_imelength= strlen(t_pchar);
  3683.                 m_oldstring=t_pchar;
  3684.                 t_pchar+=t_difference;
  3685.                 m_pchardata->mask= -1;//TF_INLINEINPUT;
  3686.                 SETBIT(m_pchardata->values,TF_INLINEINPUT);
  3687.  
  3688.                 EDT_InsertText( pMWContext, t_pchar ); 
  3689.                 EDT_SetCharacterDataAtOffset(pMWContext,m_pchardata,m_imeoffset+t_difference,m_imelength-t_difference);
  3690.             }
  3691.         }
  3692.         m_imebool=TRUE;
  3693.     }
  3694.     if (!dwSize&&!dwResultSize)// someone deleted the whole thing
  3695.     {
  3696.         EDT_SetInsertPointToOffset(pMWContext,m_imeoffset,m_imelength);
  3697.         m_pchardata->mask= -1;
  3698.         CLEARBIT(m_pchardata->values,TF_INLINEINPUT);//we are done!
  3699.         EDT_DeleteChar(pMWContext); //do nothing with error, errors here do not concern us.  probably just crossed a table boundary.            
  3700.         EDT_SetCharacterData(pMWContext,m_pchardata);
  3701.         m_imelength=0;
  3702.         m_imebool=FALSE;
  3703.     }
  3704.  
  3705.     int startloc= -1;
  3706.     int endloc= -1;
  3707.     if (( lparam & GCS_COMPATTR ) && (attributearray))
  3708.     {
  3709.         //find start location
  3710.         for (DWORD /*int*/ i=0;(startloc== -1)&&(i< dwAttrSize);i++)
  3711.         {
  3712.             if ((attributearray[i]==ATTR_TARGET_CONVERTED)||
  3713.                 ((attributearray[i]==ATTR_TARGET_NOTCONVERTED)&&!cursorPosMoved) //if the cursor position moved, domeone hit esc if there is target notconverted. gotcha MS
  3714.                 )
  3715.                 startloc=i;
  3716.         }
  3717.         if (startloc!= -1)
  3718.         {
  3719.             for (DWORD /*int*/ i=startloc;(endloc== -1)&&(i<dwAttrSize);i++)
  3720.                 if ((attributearray[i]!=ATTR_TARGET_CONVERTED)&&(attributearray[i]!=ATTR_TARGET_NOTCONVERTED))
  3721.                     endloc=i;
  3722.             if (endloc== -1)
  3723.                 endloc=dwAttrSize;
  3724.             if ((win_csid==CS_UTF8)||(win_csid==CS_UTF7))
  3725.             {
  3726.                 int32 charCount = INTL_TextByteCountToCharLen(m_csid, (unsigned char *)szComp, endloc);
  3727.                 endloc = (WORD)INTL_TextCharLenToByteCount(win_csid, t_unicodestring, charCount);
  3728.                 charCount = INTL_TextByteCountToCharLen(m_csid, (unsigned char *)szComp, startloc);
  3729.                 startloc = (WORD)INTL_TextCharLenToByteCount(win_csid, t_unicodestring, charCount);
  3730.             }
  3731.             EDT_SetInsertPointToOffset(pMWContext,m_imeoffset+startloc,endloc-startloc);
  3732.         }
  3733.     }
  3734.     if (startloc == -1)
  3735.     {
  3736.         if (lparam & GCS_CURSORPOS)
  3737.             EDT_SetInsertPointToOffset(pMWContext,m_imeoffset+cursorPos,0);
  3738.         else
  3739.             EDT_SetInsertPointToOffset(pMWContext,m_imeoffset+m_imelength,0);
  3740.     }
  3741.     if (szComp)
  3742.         delete [] szComp;
  3743.     if (szResultStr)
  3744.         delete [] szResultStr;
  3745.     if (attributearray)
  3746.         delete [] attributearray;
  3747.     XP_FREEIF(t_unicodestring);
  3748.     return TRUE;
  3749. }
  3750.  
  3751. void CNetscapeEditView::OnLButtonDown(UINT uFlags, CPoint cpPoint)
  3752. {
  3753.     if (m_imebool&&m_pime)
  3754.     {
  3755.         HIMC hIMC;
  3756.         if (hIMC = m_pime->ImmGetContext(this->m_hWnd))
  3757.         {
  3758.             m_pime->ImmNotifyIME(hIMC,NI_COMPOSITIONSTR,CPS_COMPLETE,NULL);
  3759.             m_pime->ImmReleaseContext(this->m_hWnd,hIMC);
  3760.         }
  3761.     }
  3762.     CNetscapeView::OnLButtonDown(uFlags,cpPoint);
  3763.     return;
  3764. }
  3765.  
  3766. LRESULT
  3767. CNetscapeEditView::OnInputLanguageChange(WPARAM wParam,LPARAM lParam)
  3768. {
  3769.     MWContext * pMWContext=GET_MWCONTEXT;
  3770.     if (!pMWContext)
  3771.         return FALSE;
  3772.     CString t_string;
  3773.     int t_numchar;
  3774.     int t_ansicp;
  3775.  
  3776.     INTL_CharSetInfo csi = LO_GetDocumentCharacterSetInfo(pMWContext);
  3777.     int16 win_csid = INTL_GetCSIWinCSID(csi);
  3778.     if ((win_csid==CS_UTF8)||(win_csid==CS_UTF7))    
  3779.     {
  3780.       int t_langid=(int)(lParam&0xFFFF);//only want low order word
  3781.       int t_localeid=MAKELCID(t_langid,SORT_DEFAULT);
  3782.       t_numchar=GetLocaleInfo(t_localeid,LOCALE_IDEFAULTANSICODEPAGE,0,NULL);
  3783.       t_numchar=GetLocaleInfo(t_localeid,LOCALE_IDEFAULTANSICODEPAGE,t_string.GetBuffer(t_numchar),t_numchar);
  3784.       t_string.ReleaseBuffer();
  3785.       if (!t_string.GetLength())
  3786.          return FALSE;
  3787.       t_ansicp=atoi(t_string);
  3788.       m_csid=CIntlWin::CodePageToCsid(t_ansicp);
  3789.         return CNetscapeView::DefWindowProc(WM_INPUTLANGCHANGE,wParam,lParam);
  3790.     }
  3791.     return FALSE;
  3792. }
  3793.  
  3794. LRESULT
  3795. CNetscapeEditView::OnInputLanguageChangeRequest(WPARAM wParam,LPARAM lParam)
  3796. {
  3797.     return CNetscapeView::DefWindowProc(WM_INPUTLANGCHANGEREQUEST,wParam,lParam);
  3798. }
  3799.  
  3800.  
  3801. #else //it is win16
  3802.  
  3803. void CNetscapeEditView::OnLButtonDown(UINT uFlags, CPoint cpPoint)
  3804. {
  3805.     if (m_imebool&&m_pime)
  3806.         return;
  3807.     else
  3808.         CNetscapeView::OnLButtonDown(uFlags,cpPoint);
  3809. }
  3810.  
  3811.  
  3812.  
  3813. LRESULT
  3814. CNetscapeEditView::OnReportIme(WPARAM wParam,LPARAM lParam)
  3815. {
  3816.     switch (wParam)
  3817.         {
  3818.         case IR_UNDETERMINE:
  3819.             return OnImeChangeComposition((HGLOBAL)lParam);
  3820.             break;
  3821.         case IR_CLOSECONVERT://should not be getting these!
  3822.             OnImeEndComposition();
  3823.             break;
  3824.         case IR_OPENCONVERT:
  3825.             initializeIME();//should not be getting these!
  3826.             break;
  3827.         case IR_STRINGSTART://should not be getting these!
  3828.             break;
  3829.         case IR_STRINGEND:    //should not be getting these!
  3830.             break;
  3831.         case IR_CHANGECONVERT:
  3832.             initializeIME();//should not be getting these!
  3833.             break;
  3834.         case IR_STRINGEX:
  3835.             return insertStringEx((HGLOBAL)lParam);
  3836.             break;
  3837.         default :
  3838.             break;
  3839.         }
  3840.     return TRUE;//doesnt matter on default returns
  3841. }
  3842.  
  3843. BOOL
  3844. CNetscapeEditView::initializeIME()
  3845. {
  3846.     if (!m_pime)
  3847.     {    
  3848.         m_pime=m_resourcedll.CreateImeDll();
  3849.     }
  3850.     if (!m_pime)
  3851.     {
  3852.         return FALSE; //may be english version.
  3853.     }
  3854.     if (!m_hIME)
  3855.         ImeCreate(this->GetSafeHwnd());
  3856.     LPIMESTRUCT lpIme;
  3857.     if (!(lpIme = (LPIMESTRUCT)GlobalLock(m_hIME)))
  3858.         return FALSE;
  3859.  
  3860.        CPoint point=GetCaretPos();
  3861.     ClientToScreen(&point);
  3862.     lpIme->fnc=IME_SETCONVERSIONWINDOW;
  3863.     lpIme->wParam=MCW_HIDDEN;
  3864.     CRect t_rect;
  3865.     GetClientRect(t_rect);
  3866.     if (t_rect.IsRectEmpty())//this is necessary for 1st run through when window isnt sized properly.
  3867.     {
  3868.         t_rect.left=5;
  3869.         t_rect.top=5;
  3870.         t_rect.right=50;
  3871.         t_rect.bottom=20;
  3872.     }
  3873.     if ((point.x<0)||(point.x>GetSystemMetrics(SM_CXSCREEN))||(point.y<0)||(point.y>GetSystemMetrics(SM_CYSCREEN))) //something went wrong. bad client to screen conversion
  3874.     {
  3875.         point.x=0;
  3876.         point.y=0;
  3877.     }
  3878.  
  3879.     lpIme->lParam1=MAKELPARAM(point.x, point.y);
  3880.     lpIme->lParam2=MAKELPARAM(point.x, point.y);//BAD BAD BAD CHANGE!!!
  3881.     lpIme->lParam3=MAKELPARAM(point.x+t_rect.right, point.y+20);//BAD BAD BAD CHANGE!!!
  3882.     GlobalUnlock(m_hIME);
  3883.     m_pime->SendIMEMessageEx(this->GetSafeHwnd(),m_lIMEParam);
  3884.  
  3885.     CWinCX    * pContext = GetContext();
  3886.     if ((!m_imebool)&&(pContext))
  3887.     {
  3888.         MWContext * pMWContext = pContext->GetContext();
  3889.         m_imeoffset=EDT_GetInsertPointOffset(pMWContext);//used for calls to backend
  3890.         m_imelength=0;
  3891.         XP_FREEIF(m_pchardata);
  3892.         m_pchardata=EDT_GetCharacterData(pMWContext);
  3893.     }
  3894.     ImeSetFont(this->GetSafeHwnd(),(HFONT)GetStockObject(SYSTEM_FONT));
  3895.     m_oldstring="";
  3896.     return TRUE;
  3897. }
  3898.  
  3899.  
  3900. void    CNetscapeEditView::ImeCreate(HWND hWnd)
  3901. {
  3902.     HDC         hDC;
  3903.     TEXTMETRIC  tm;
  3904.     LPIMEPRO    lpImepro;
  3905.     CString     t_desc,t_name;
  3906.     m_hIME = GlobalAlloc(GHND, (LONG)sizeof(IMESTRUCT));
  3907.     m_lIMEParam = MAKELPARAM(m_hIME, 0);
  3908.  
  3909.     return;
  3910. }
  3911.  
  3912. /*-----------------------------------------------------------------------------
  3913.  
  3914. ImeDestroy
  3915.  
  3916. WM_DESTROY
  3917.  
  3918. -----------------------------------------------------------------------------*/
  3919. void    CNetscapeEditView::ImeDestroy(void)
  3920. {
  3921.     GlobalFree(m_hIME);
  3922.     return;
  3923. }
  3924.  
  3925.  
  3926. /*-----------------------------------------------------------------------------
  3927.  
  3928.     ImeMoveConvertWin
  3929.  
  3930.  
  3931.  
  3932. -----------------------------------------------------------------------------*/
  3933. void    CNetscapeEditView::ImeMoveConvertWin(HWND hWnd,int x,int y)
  3934. {
  3935.     if (!initializeIME())
  3936.     {
  3937.         return;
  3938.     }
  3939.     LPIMESTRUCT lpIme;
  3940.  
  3941.     if (lpIme = (LPIMESTRUCT)GlobalLock(m_hIME)) {
  3942.         lpIme->fnc = IME_SETCONVERSIONWINDOW;
  3943.         /* x == -1 && y == -1 */
  3944.         if (x == -1 && y == -1)
  3945.             lpIme->wParam = MCW_DEFAULT;
  3946.         else
  3947.             if (0) {//this decides if it needs to wrap. if so, throw it to bottom left
  3948.  
  3949.                 lpIme->wParam = MCW_WINDOW;
  3950.                 lpIme->lParam1 = MAKELPARAM(x, y);
  3951.             } else {
  3952.  
  3953.                 lpIme->wParam = MCW_DEFAULT;
  3954.             }
  3955.         GlobalUnlock(m_hIME);
  3956.  
  3957.         LRESULT t_result=m_pime->SendIMEMessageEx(hWnd, m_lIMEParam);
  3958.     }
  3959.     return;
  3960. }
  3961.  
  3962.  
  3963.  
  3964. /*-----------------------------------------------------------------------------
  3965.  
  3966.     ImeSetFont
  3967.  
  3968. -----------------------------------------------------------------------------*/
  3969. HFONT   CNetscapeEditView::ImeSetFont(HWND hWnd,HFONT hFont)
  3970. {
  3971.     LPIMESTRUCT lpIme;
  3972.     HFONT       hResult = 0;
  3973.  
  3974.     if (lpIme = (LPIMESTRUCT)GlobalLock(m_hIME)) {
  3975.         /* IME_SETCONVERSIONFONT*/
  3976.         lpIme->fnc = IME_SETCONVERSIONFONT;
  3977.         /*IME*/
  3978.         lpIme->wParam = (WPARAM)hFont;
  3979.         LRESULT t_result=m_pime->SendIMEMessageEx(hWnd, m_lIMEParam);
  3980.         if (lpIme = (LPIMESTRUCT)GlobalLock(m_hIME)) 
  3981.         {
  3982.             hResult = (HFONT)lpIme->wParam;
  3983.             GlobalUnlock(m_hIME);
  3984.         }
  3985.         GlobalUnlock(m_hIME);
  3986.     }
  3987.     return hResult;
  3988. }
  3989.  
  3990.  
  3991. void CNetscapeEditView::OnImeStartComposition()
  3992. {
  3993.     if (!initializeIME())
  3994.     {
  3995.         assert(FALSE);
  3996.         return;
  3997.     }
  3998.     return;
  3999. }
  4000.  
  4001. void
  4002. CNetscapeEditView::OnImeEndComposition()
  4003. {
  4004.     if (!m_pime)
  4005.     {
  4006.         assert(FALSE);
  4007.         return;
  4008.     }
  4009.     CWinCX    * pContext = GetContext();
  4010.     MWContext * pMWContext = pContext->GetContext();
  4011.     m_pchardata->mask= -1;
  4012.     CLEARBIT(m_pchardata->values,TF_INLINEINPUT);//we are done!
  4013.  
  4014.     EDT_SetCharacterDataAtOffset(pMWContext,m_pchardata,m_imeoffset,m_imelength);
  4015.  
  4016.     EDT_SetInsertPointToOffset(pMWContext,m_imeoffset+m_imelength,0);
  4017.  
  4018.     m_imebool=FALSE;
  4019.     m_imeoffset=0;
  4020.     return;
  4021. }
  4022.  
  4023.  
  4024.  
  4025. LRESULT CNetscapeEditView::insertStringEx(HGLOBAL p_global)
  4026. {
  4027.     if (!m_imebool)
  4028.     {
  4029.         if (!initializeIME())
  4030.         {
  4031.             assert(FALSE);
  4032.             return FALSE;
  4033.         }
  4034.         MWContext * pMWContext = GET_MWCONTEXT;
  4035.         //get rid of previous text! here
  4036.         if (pMWContext)
  4037.         {
  4038.             if (EDT_IsSelected(pMWContext))
  4039.             {
  4040.                 EDT_DeleteChar(pMWContext);//message boxes here would screw up IME
  4041.                 //do nothing with error, errors here do not concern us.  probably just crossed a table boundary.            
  4042.             }
  4043.         }
  4044.     }
  4045.     if (!p_global)
  4046.         return FALSE;
  4047.     char *t_pimestring=NULL;
  4048.     LPSTRINGEXSTRUCT t_struct=(LPSTRINGEXSTRUCT)GlobalLock(p_global);
  4049.     if (!t_struct)
  4050.         return FALSE;
  4051.     if (!t_struct->uDeterminePos) //no string??
  4052.     {
  4053.         GlobalUnlock(p_global);
  4054.         return FALSE;
  4055.     }
  4056.     t_pimestring=XP_STRDUP(((char *)t_struct)+t_struct->uDeterminePos);//use strdup because we want to release this global quickly
  4057.     GlobalUnlock(p_global);
  4058.  
  4059.     CWinCX    * pContext = GetContext();
  4060.     MWContext * pMWContext = pContext->GetContext();
  4061.  
  4062.     EDT_SetInsertPointToOffset(pMWContext,m_imeoffset,0);
  4063.     EDT_InsertText( pMWContext, t_pimestring ); 
  4064.     XP_FREEIF(t_pimestring);
  4065.     return TRUE;
  4066. }
  4067.  
  4068.  
  4069.  
  4070. LRESULT CNetscapeEditView::OnImeChangeComposition(HGLOBAL p_global)
  4071. {
  4072.     int t_justturnedon=FALSE;
  4073.     if (!p_global)
  4074.         return TRUE;
  4075.     if (!m_imebool)
  4076.     {
  4077.         if (!initializeIME())
  4078.         {
  4079.             assert(FALSE);
  4080.             return FALSE;
  4081.         }
  4082.         MWContext * pMWContext = GET_MWCONTEXT;
  4083.         //get rid of previous text! here
  4084.         if (pMWContext)
  4085.         {
  4086.             if (EDT_IsSelected(pMWContext))
  4087.             {
  4088.                 EDT_DeleteChar(pMWContext);//message boxes here would screw up IME
  4089.                 //do nothing with error, errors here do not concern us.  probably just crossed a table boundary.            
  4090.             }
  4091.         }
  4092.         m_imebool=TRUE;
  4093.         t_justturnedon=TRUE;
  4094.     }
  4095.  
  4096.     char *t_pimestring=NULL;
  4097.     char *t_pdeterminestring=NULL;
  4098.     char *t_attribarray=NULL;
  4099.     DWORD dwSize=0;
  4100.     DWORD dwAttrSize=0;
  4101.     WORD cursorPos=0;
  4102.     LPUNDETERMINESTRUCT t_struct=(LPUNDETERMINESTRUCT)GlobalLock(p_global);
  4103.     char *t_undetchar=((char *)t_struct)+t_struct->uUndetTextPos;
  4104.     char *t_detchar=((char *)t_struct)+t_struct->uDetermineTextPos;
  4105.     cursorPos=t_struct->uCursorPos;
  4106.     BOOL cursorPosMoved=cursorPos!=m_imeoldcursorpos;
  4107.     m_imeoldcursorpos=cursorPos;
  4108.     CWinCX    * pContext = GetContext();
  4109.     MWContext * pMWContext = pContext->GetContext();
  4110.     
  4111.     if ((t_struct->uUndetTextPos)&&(strlen(t_undetchar))) //undetermined string
  4112.     {
  4113.         if ((t_struct->uDetermineTextPos)&&(strlen(t_detchar))) //also determined string??  that means user hit space and is continuing
  4114.         {
  4115.             t_pdeterminestring=XP_STRDUP(t_detchar);//+1 for null
  4116.         }
  4117.         t_pimestring=XP_STRDUP(t_undetchar);
  4118.         if (t_struct->uUndetAttrPos)
  4119.         {
  4120.             dwAttrSize=strlen(t_undetchar);
  4121.             char *t_ptr=((char *)t_struct)+t_struct->uUndetAttrPos;
  4122.             t_attribarray=new char[dwAttrSize];
  4123.             memcpy(t_attribarray,t_ptr,dwAttrSize);
  4124.         }
  4125.     }
  4126.     else
  4127.         if ((t_struct->uDetermineTextPos)&&(strlen(t_detchar)))
  4128.         {
  4129.             t_pdeterminestring=XP_STRDUP(t_detchar);
  4130.         }
  4131.         else
  4132.         {
  4133.             GlobalUnlock(p_global);
  4134.             if (!t_justturnedon)
  4135.             {
  4136.                 EDT_SetInsertPointToOffset(pMWContext,m_imeoffset,m_imelength);
  4137.                 EDT_DeleteChar(pMWContext); //do nothingwith error, errors here do not concern us.  probably just crossed a table boundary.            
  4138.                 m_imelength=0;
  4139.             }
  4140.             OnImeEndComposition();
  4141.             return TRUE;
  4142.         }
  4143.     GlobalUnlock(p_global);
  4144.     if ((!t_pimestring)&&(!t_pdeterminestring))
  4145.         return FALSE;
  4146.  
  4147.  
  4148.     int t_offset=m_imeoffset;//used in the case of optipization
  4149.     if (t_pdeterminestring)//we may have both determined and undetermined strings if this is true
  4150.     {
  4151.         m_pchardata->mask= -1;
  4152.         CLEARBIT(m_pchardata->values,TF_INLINEINPUT);//we are done!
  4153.         if (findDifference(m_oldstring,t_pdeterminestring,pMWContext)!= -1) //different strings
  4154.         {
  4155.             EDT_SetInsertPointToOffset(pMWContext,m_imeoffset,m_imelength);
  4156.             EDT_InsertText( pMWContext, t_pdeterminestring ); 
  4157.         }
  4158.         EDT_SetCharacterDataAtOffset(pMWContext,m_pchardata,m_imeoffset,strlen(t_pdeterminestring));
  4159.         m_imeoffset+=strlen(t_pdeterminestring);
  4160.         m_imelength=0;//just replaced previous string. no need to do so again
  4161.         EDT_SetInsertPointToOffset(pMWContext,m_imeoffset,m_imelength);  //or m_imeoffset,0
  4162.         m_oldstring="";
  4163.         m_imebool=FALSE;
  4164.         m_imeoldcursorpos= -1;
  4165.     }
  4166.     if (t_pimestring)
  4167.     {
  4168.         int t_difference=findDifference(m_oldstring,t_pimestring,pMWContext);
  4169.         if (!m_imelength||(-1 != t_difference)) //they are the same if -1 is returned
  4170.         {
  4171.             t_difference=max(t_difference,0);  //-1 becomes 0 if no old imelength
  4172.             if (t_difference>=strlen(t_pimestring)) //someone hit backspace!
  4173.             {
  4174.                 EDT_SetInsertPointToOffset(pMWContext,m_imeoffset+t_difference,m_imelength-t_difference);
  4175.                 EDT_DeleteChar(pMWContext); //do nothing with error, errors here do not concern us.  probably just crossed a table boundary.            
  4176.                 m_imelength-=m_imelength-t_difference;
  4177.                 m_oldstring=m_oldstring.Mid(0,m_imelength);
  4178.             }
  4179.             else
  4180.             {
  4181.                 if (t_difference>=m_imelength)
  4182.                     EDT_SetInsertPointToOffset(pMWContext,m_imeoffset+m_imelength,0);
  4183.                 else
  4184.                     EDT_SetInsertPointToOffset(pMWContext,m_imeoffset+t_difference,m_imelength-t_difference);
  4185.                 EDT_InsertText(pMWContext,t_pimestring+t_difference);
  4186.                 m_imelength= strlen(t_pimestring);
  4187.                 m_oldstring=t_pimestring;
  4188.                 m_pchardata->mask= -1;
  4189.                 SETBIT(m_pchardata->values,TF_INLINEINPUT);//we are done!
  4190.                 EDT_SetCharacterDataAtOffset(pMWContext,m_pchardata,m_imeoffset+t_difference,m_imelength-t_difference);
  4191.             }
  4192.         }
  4193.         m_imebool=TRUE;
  4194.     }
  4195.     int startloc=-1;
  4196.     int endloc=-1;
  4197.     if (dwAttrSize)
  4198.     {
  4199.         //find start location
  4200.         for (int i=0;(startloc== -1)&&(i<dwAttrSize);i++)
  4201.         {
  4202.             if ((t_attribarray[i]==ATTR_TARGET_CONVERTED)||
  4203.                 ((t_attribarray[i]==ATTR_TARGET_NOTCONVERTED)&&!cursorPosMoved) //if the cursor position moved, domeone hit esc if there is target notconverted. gotcha MS
  4204.                 )
  4205.                 startloc=i;
  4206.         }
  4207.         if (startloc!= -1)
  4208.         {
  4209.             for (int i=startloc;(endloc== -1)&&(i<dwAttrSize);i++)
  4210.                 if ((t_attribarray[i]!=ATTR_TARGET_CONVERTED)&&(t_attribarray[i]!=ATTR_TARGET_NOTCONVERTED))
  4211.                     endloc=i;
  4212.             if (endloc== -1)
  4213.                 endloc=dwAttrSize;
  4214.             EDT_SetInsertPointToOffset(pMWContext,m_imeoffset+startloc,endloc-startloc);
  4215.         }
  4216.     }
  4217.     if (startloc== -1) //check cursor position
  4218.     {
  4219.         EDT_SetInsertPointToOffset(pMWContext,m_imeoffset+cursorPos,0);
  4220.     }
  4221.     XP_FREEIF(t_pimestring);
  4222.     XP_FREEIF(t_pdeterminestring);
  4223.     if (t_attribarray)
  4224.         delete []t_attribarray;
  4225.     return TRUE;
  4226. }
  4227.  
  4228.  
  4229. #endif//XP_WIN32 else win16
  4230.  
  4231.  
  4232. #endif //_IME_COMPOSITION
  4233.  
  4234.  
  4235. void CNetscapeEditView::BuildEditHistoryMenu(HMENU hMenu, int iStartItem)
  4236. {
  4237.     int nCount = GetMenuItemCount(hMenu);
  4238.     int i;
  4239.     
  4240.     // Delete existing menu
  4241.     for( i = nCount - 1; i >= iStartItem; i-- )
  4242.         DeleteMenu(hMenu, i, MF_BYPOSITION);
  4243.  
  4244.     char * pUrl = NULL;
  4245.     char * pMenuItem = NULL;
  4246.     for( i = 0; i < MAX_EDIT_HISTORY_LOCATIONS; i++ )
  4247.     {
  4248.         if(EDT_GetEditHistory(GET_MWCONTEXT, i, &pUrl, NULL))
  4249.         {
  4250.             // Condense in case URL is too long for the menu
  4251.             // Note: pUrl is static string - don't free it
  4252.             CString csMenuString = pUrl;
  4253.             WFE_CondenseURL(csMenuString, MAX_MENU_ITEM_LENGTH, FALSE);
  4254.  
  4255.             // Add 1 - 9 as first character menu accelerator
  4256.             if (i < 9)
  4257.                 pMenuItem = PR_smprintf("&%d %s", i+1, csMenuString);
  4258.             else
  4259.                 pMenuItem = PR_smprintf("  %s", csMenuString);
  4260.             
  4261.             if( pMenuItem )
  4262.             {
  4263.                 AppendMenu(hMenu, MF_STRING, ID_EDIT_HISTORY_BASE+i, pMenuItem);
  4264.                 XP_FREE(pMenuItem);
  4265.             }
  4266.         }
  4267.     }
  4268. }
  4269.  
  4270. void CNetscapeEditView::OnCheckSpelling()
  4271. {
  4272.     MWContext *pMWContext = GET_MWCONTEXT;
  4273.  
  4274.     CHtmlSpellChecker SpellChecker(GET_MWCONTEXT, this);
  4275.  
  4276.     if (SpellChecker.ProcessDocument() != 0){
  4277.        // ASSERT(FALSE);
  4278.         TRACE0("SpellChecker.ProcessDocument() != 0\n");
  4279.     }
  4280. }
  4281.  
  4282. void CNetscapeEditView::OnSpellingLanguage()
  4283. {
  4284. }
  4285.  
  4286. // Button drop down menu commands and menu strings
  4287. const UINT idArrayNewDoc[] = { ID_EDT_NEW_DOC_BLANK,
  4288.                                ID_EDT_NEW_DOC_FROM_TEMPLATE,
  4289.                                ID_COMMAND_PAGE_FROM_WIZARD };
  4290.  
  4291. const UINT strArrayNewDoc[] = { IDS_NEW_DOC_BLANK,
  4292.                                 IDS_NEW_DOC_FROM_TEMPLATE,
  4293.                                 IDS_NEW_DOC_FROM_WIZARD };
  4294.  
  4295. const UINT idArrayPrint[] = { ID_FILE_PRINT,
  4296.                               ID_FILE_PAGE_SETUP,
  4297.                               ID_FILE_PRINT_PREVIEW };
  4298.  
  4299. const UINT strArrayPrint[] = { IDS_FILE_PRINT,
  4300.                                IDS_FILE_PAGE_SETUP,
  4301.                                IDS_FILE_PRINT_PREVIEW };
  4302.  
  4303. LRESULT CNetscapeEditView::OnButtonMenuOpen(WPARAM wParam, LPARAM lParam)
  4304. {
  4305.  
  4306.     HMENU hMenu = (HMENU) lParam;
  4307.     UINT nCommand = (UINT) LOWORD(wParam);
  4308.  
  4309.     const UINT *idArray = NULL;
  4310.     const UINT *strArray = NULL;
  4311.     int nSize = 3;
  4312.     
  4313.     if( nCommand == ID_EDT_NEW_DOC_BLANK )
  4314.     {
  4315.         idArray = idArrayNewDoc;
  4316.         strArray = strArrayNewDoc;
  4317.     } 
  4318.     else if( nCommand == ID_FILE_OPEN )
  4319.     {
  4320.         // Menu length is dynamic - don't use fixed arrays
  4321.         // First 2 items are always the same
  4322.         AppendMenu(hMenu, MF_STRING, ID_FILE_OPEN, szLoadString(IDS_FILE_OPEN));
  4323.         AppendMenu(hMenu, MF_STRING, ID_FILE_OPENURL, szLoadString(IDS_FILE_OPENURL));
  4324.         AppendMenu(hMenu, MF_SEPARATOR, 0, 0);
  4325.  
  4326.         // The rest of the menu comes from the history list of recently-edited URLs
  4327.         BuildEditHistoryMenu(hMenu, 3);
  4328.     } 
  4329.     else if( nCommand == ID_FILE_PRINT )
  4330.     {
  4331.         idArray = idArrayPrint;
  4332.         strArray = strArrayPrint;
  4333.     }
  4334.  
  4335.     if ( idArray )
  4336.     {
  4337.         CString str;
  4338.         for(int i = 0; i < nSize; i++)
  4339.         {
  4340.             str.LoadString(strArray[i]);
  4341.             AppendMenu(hMenu, MF_STRING, idArray[i], (const char*) str);
  4342.         }
  4343.     }
  4344.     return 1;
  4345. }
  4346.  
  4347. ////////////////////////////////////////
  4348. // Drag/drop functions
  4349.  
  4350. // Special non-blinking drop indicater to avoid stealing 
  4351. //  the one-and-only system caret
  4352. void DisplayDropCaret(HDC hDC, CRect cRect)
  4353. {
  4354.     int iRop = ::GetROP2(hDC);
  4355.     HPEN hPenOld = (HPEN)SelectObject(hDC, GetStockObject(WHITE_PEN));
  4356.     SetROP2(hDC, R2_XORPEN);
  4357.  
  4358.     // Solid, non-blinking "caret"
  4359.     InvertRect(hDC, LPRECT(cRect));
  4360.  
  4361.     // Triangle at top of caret
  4362.     MoveToEx(hDC, cRect.left - 1, cRect.top, 0);
  4363.     LineTo(hDC, cRect.left - 1, cRect.top + 2);
  4364.     MoveToEx(hDC, cRect.right, cRect.top, 0);
  4365.     LineTo(hDC, cRect.right, cRect.top + 2);
  4366.  
  4367.     MoveToEx(hDC, cRect.left - 2, cRect.top - 1, 0);
  4368.     LineTo(hDC, cRect.right + 2, cRect.top - 1);
  4369.     MoveToEx(hDC, cRect.left - 3, cRect.top - 2, 0);
  4370.     LineTo(hDC, cRect.right + 3, cRect.top - 2);
  4371.  
  4372.     SetROP2(hDC, iRop);
  4373.     SelectObject(hDC, hPenOld);
  4374. }
  4375.  
  4376. // Checks file extension for .gif, *.jpg etc.
  4377. BOOL CNetscapeEditView::CanSupportImageFile(const char * pFilename)
  4378. {
  4379.     if( pFilename ){
  4380.         const char * pExt = strrchr(pFilename, '.');
  4381.         if( pExt &&
  4382.             0 == _strcmpi( pExt, ".gif")  ||
  4383.             0 == _strcmpi( pExt, ".jpg")  ||
  4384.             0 == _strcmpi( pExt, ".jpeg") ||  
  4385.             0 == _strcmpi( pExt, ".png")  ||
  4386.             0 == _strcmpi( pExt, ".bmp") ) {
  4387.             return TRUE;
  4388.         }
  4389.     }
  4390.     return FALSE;
  4391. }
  4392.  
  4393. //////////////////////////////////////////////////////////////////////////////
  4394. CEditViewDropTarget::CEditViewDropTarget() :
  4395.     m_nDragType(0),
  4396.     m_dwLastKeyState(0),
  4397.     m_cLastPoint(-1,-1),
  4398.     m_LastDropEffect(DROPEFFECT_NONE)
  4399. {
  4400. }
  4401.  
  4402.  
  4403. DROPEFFECT CEditViewDropTarget::OnDragEnter(CWnd* pWnd, 
  4404.                 COleDataObject* pDataObject, DWORD dwKeyState, CPoint point )
  4405. {
  4406.     if(pDataObject->IsDataAvailable(
  4407.         ::RegisterClipboardFormat(vCardClipboardFormat)) )
  4408.             return DROPEFFECT_NONE;    
  4409.  
  4410.     m_nDragType = FE_DRAG_UNKNOWN;
  4411.     m_nIsOKDrop = FALSE;
  4412.     CNetscapeEditView * pView = (CNetscapeEditView*)pWnd;
  4413.     MWContext *pMWContext;
  4414.     if( pView->GetContext() == NULL || (pMWContext = pView->GetContext()->GetContext()) == NULL )
  4415.         return DROPEFFECT_NONE;
  4416.     
  4417.     pView->m_bDragOver = TRUE;
  4418.  
  4419.     // This gets called no matter who starts a drag,
  4420.     //  so look for types we are interested in
  4421.     CLIPFORMAT nImageFormat = RegisterClipboardFormat(NETSCAPE_IMAGE_FORMAT);
  4422.     if( pDataObject->IsDataAvailable(nImageFormat) ) {
  4423.         m_nDragType = FE_DRAG_IMAGE;
  4424.     } else if( pDataObject->IsDataAvailable(RegisterClipboardFormat(NETSCAPE_BOOKMARK_FORMAT)) ) {
  4425.         m_nDragType = FE_DRAG_LINK;
  4426.     } else if( pDataObject->IsDataAvailable(RegisterClipboardFormat(NETSCAPE_EDIT_FORMAT)) ) {
  4427.         m_nDragType = EDT_IsDraggingTable(pMWContext) ? FE_DRAG_TABLE : FE_DRAG_HTML;
  4428.     } else if( pDataObject->IsDataAvailable(CF_TEXT) 
  4429. #ifdef XP_WIN32
  4430.                 || pDataObject->IsDataAvailable(CF_UNICODETEXT) 
  4431. #endif
  4432.                 ) {
  4433.         m_nDragType = FE_DRAG_TEXT;
  4434. #ifdef XP_WIN32
  4435.     } else if( pDataObject->IsDataAvailable(CF_HDROP) ) {
  4436.         // Check what kind of file it is
  4437.         // We accept HTML for link creation,
  4438.         // GIF and JPG for image insertion
  4439.         
  4440.         HDROP handle = (HDROP)pDataObject->GetGlobalData(CF_HDROP);
  4441.         char pFilename[1024];
  4442.         if ( DragQueryFile(handle, 0, 
  4443.                            pFilename, 1024) ) {
  4444.             CString csFilename(pFilename);
  4445.             int iLastDot = csFilename.ReverseFind('.');
  4446.             if(iLastDot>0) {
  4447.                 CString csExt = csFilename.Mid(iLastDot);
  4448.                 if ( 0 == csExt.CompareNoCase(".htm") ||
  4449.                      0 == csExt.CompareNoCase(".html") ||
  4450.                      0 == csExt.CompareNoCase(".shtml") ) {
  4451.                     m_nDragType = FE_DRAG_LINK;
  4452.                 } 
  4453.                 else if ( pView->CanSupportImageFile(LPCSTR(csExt)) ) {
  4454.                     m_nDragType = FE_DRAG_IMAGE;
  4455.                 }
  4456.             }
  4457.         }
  4458.         // Didn't find any files of interest                
  4459.         if ( m_nDragType == FE_DRAG_UNKNOWN ){
  4460.             return(DROPEFFECT_NONE);
  4461.         }
  4462. #endif
  4463.     } else {
  4464.         return(DROPEFFECT_NONE);
  4465.     }
  4466.     m_nIsOKDrop = TRUE;
  4467.  
  4468.     if ( pView->GetContext()->IsDragging() ) {
  4469.         return(DROPEFFECT_MOVE);
  4470.     } else {
  4471.         return(DROPEFFECT_COPY);
  4472.     }
  4473. }
  4474.  
  4475. DROPEFFECT CEditViewDropTarget::OnDragOver(CWnd* pWnd, 
  4476.                 COleDataObject* pDataObject, DWORD dwKeyState, CPoint cPoint )
  4477. {
  4478.     if ( !m_nIsOKDrop )
  4479.     {
  4480.         return(DROPEFFECT_NONE);
  4481.     }
  4482.     DROPEFFECT DropEffect = DROPEFFECT_NONE;
  4483.  
  4484.     // Simply return last state if position and keystate is the same
  4485.     if( dwKeyState == m_dwLastKeyState && cPoint == m_cLastPoint )
  4486.     {
  4487.         return(m_LastDropEffect);
  4488.     }
  4489.     m_dwLastKeyState = dwKeyState;
  4490.     m_cLastPoint = cPoint;
  4491.  
  4492.     CNetscapeEditView * pView = (CNetscapeEditView *) pWnd;
  4493.  
  4494.     // Do Caret-moving to show where we will drop
  4495.     CWinCX *     pContext = pView->GetContext();
  4496.     MWContext  * pMWContext = pContext->GetContext();
  4497.     if ( pContext && pMWContext )
  4498.     {
  4499.         // Don't allow dropping on selection if drag source is our view
  4500.         if( pContext->IsDragging() && pContext->PtInSelectedRegion(cPoint, TRUE) )
  4501.         {
  4502.             return(DROPEFFECT_NONE);
  4503.         }
  4504.         
  4505.         switch ( m_nDragType )
  4506.         {
  4507.             case FE_DRAG_LINK:
  4508.             // Drop HTML or image anywhere we can drop text:
  4509.             case FE_DRAG_HTML:
  4510.             case FE_DRAG_TABLE:
  4511.             case FE_DRAG_IMAGE:
  4512.              // If no selected text, fall through to allow inserting bookmark anywhere
  4513.             case FE_DRAG_TEXT:
  4514.                 int32 xVal, yVal;        
  4515.                 pView->ClientToDocXY( cPoint, &xVal, &yVal );        
  4516. #if 0
  4517. // Let back-end destroy caret if it needs to
  4518.                 // This should be destroyed (bEnabled = FALSE) if we don't have focus?
  4519.                 if ( pView->m_caret.bEnabled && pView->m_caret.cShown )
  4520.                 {
  4521.                     FE_DestroyCaret(pMWContext);
  4522.                 }
  4523. #endif
  4524.                 // Note: This will also handle feedback for where to drop table/cells
  4525.                 if( EDT_PositionDropCaret(pMWContext, xVal, yVal) )
  4526.                 {
  4527.                     // Figure out what drag cursor to use
  4528.                     // TODO: This gets messier when doing drag between 2 frames
  4529.                     //       Need to know if source is editor vs. browser
  4530.                     //       to know when to allow move or copy 
  4531.                     if ( pContext->IsDragging() && 
  4532.                          !(dwKeyState & MK_CONTROL) ) {
  4533.                         // We are draging within the frame
  4534.                         DropEffect = DROPEFFECT_MOVE;
  4535.                     } else {
  4536.                         DropEffect = DROPEFFECT_COPY;
  4537.                     }
  4538.                 }
  4539.                 break;
  4540.         }
  4541.     }
  4542.  
  4543.     m_LastDropEffect = DropEffect;
  4544.  
  4545.     return(DropEffect);
  4546. }
  4547.  
  4548. BOOL CEditViewDropTarget::OnDrop(CWnd* pWnd, 
  4549.                 COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint cPoint)
  4550. {
  4551.     if(!pDataObject || !pWnd)
  4552.         return(FALSE);
  4553.  
  4554.     CNetscapeEditView *pView = (CNetscapeEditView *)pWnd;
  4555.     pView->m_bDragOver = FALSE;
  4556.  
  4557.     // Use paste routine shared with clipboard pasting
  4558.     BOOL bResult = (pView->DoPasteItem(pDataObject, &cPoint, 
  4559.                                dropEffect == DROPEFFECT_MOVE ));
  4560.  
  4561.  
  4562.     // TRACE2("OnDrop m_hWnd=%X, SafeHwnd=%X\n", pWnd->m_hWnd, pWnd->GetSafeHwnd() );
  4563.     MWContext * pMWContext = pView->GetContext()->GetContext();
  4564.     if ( EDT_IS_EDITOR(pMWContext)  &&
  4565.          ::GetFocus() != pWnd->m_hWnd && pView->m_caret.bEnabled ) {
  4566.         // Kill caret if we don't have focus
  4567.         FE_DestroyCaret(pMWContext);
  4568.         pView->m_caret.cShown = 0;
  4569.         pView->m_caret.bEnabled = FALSE;
  4570.         DestroyCaret();
  4571.     }    
  4572.     return bResult;
  4573. }
  4574.  
  4575. void CEditViewDropTarget::OnDragLeave(CWnd* pWnd)
  4576. {
  4577.     // Note: We don't come here if we drop into our view
  4578.     CNetscapeEditView * pView = (CNetscapeEditView *) pWnd;
  4579.     
  4580.     pView->m_bDragOver = FALSE;
  4581.  
  4582.     // Restore caret coordinates
  4583.     if ( pView->m_caret.bEnabled ) {
  4584.         pView->m_caret.cShown = 0;
  4585.         TRACE0("OnDragLeave: caret disabled\n");
  4586.         pView->m_caret.bEnabled = FALSE;
  4587.         DestroyCaret();
  4588.     }
  4589. }
  4590. // end of CEditViewDropTarget
  4591.  
  4592. #endif // EDITOR
  4593.