home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / winfe / edtable.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  51.0 KB  |  1,538 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. // edtable.cpp : implementation file
  20. //
  21.  
  22. #include "stdafx.h"
  23. #include "property.h"
  24. #include "edtable.h"
  25. #include "styles.h"
  26. #include "edt.h"
  27. #include "edprops.h"
  28. #include "nethelp.h"
  29. #include "xp_help.h"
  30. #include "prefinfo.h"
  31. #include "prefapi.h"
  32.  
  33. // the dialog box & string resources are in edtrcdll DLL
  34. #include "edtrcdll\src\resource.h"
  35.  
  36. // Global string in EDFRAME.CPP: "Don't change"
  37. extern char * ed_pDontChange;
  38.  
  39. // Convert the front-end valign (0..2) to the back end alignment codes.
  40.  
  41. // FE Vertical:     Top, Center, Bottom, Baseline
  42. // FE Horizontal:   Left, center, right
  43. static const ED_Alignment kFEToXPVAlign[4] = {ED_ALIGN_ABSTOP, ED_ALIGN_ABSCENTER, ED_ALIGN_ABSBOTTOM, ED_ALIGN_BASELINE};
  44. static const ED_Alignment kFEToXPAlign[3] = {ED_ALIGN_LEFT, ED_ALIGN_ABSCENTER, ED_ALIGN_RIGHT };
  45. // Base -1 (default = -1)
  46. // default center left right top bottom baseline abscenter absbotom abstop
  47. static const int kXPToFEAlign[10] =  {0,  1,  0,  2, -1, -1, -1, 1, -1, -1};  // Default is shown as LEFT in listbox
  48. static const int kXPToFEVAlign[10] = {1, -1, -1, -1,  0,  2,  3, 1,  2,  0};  // Default is shown as CENTER in listbox
  49.  
  50. static const ED_HitType kFEToXPSelType[3] = {ED_HIT_SEL_CELL, ED_HIT_SEL_ROW, ED_HIT_SEL_COL};
  51. static const int kXPToFESelType[10] = {-1, -1, 2, 1, 0, 0, -1, -1, -1, -1};
  52.  
  53.  
  54. void SetColorHelper(BOOL bOverride, COLORREF crColor, LO_Color** ppLoColor)
  55. {
  56.     if ( !bOverride || crColor == DEFAULT_COLORREF) {
  57.         if ( *ppLoColor ) {
  58.             XP_FREE(*ppLoColor);
  59.         }
  60.         *ppLoColor = NULL;     /* null in the default case */
  61.     }
  62.     else {
  63.         // Allocates the pColorBackground pointer.
  64.         WFE_SetLO_ColorPtr( crColor, ppLoColor );
  65.     }
  66. }
  67.  
  68. void GetColorHelper(LO_Color* pLoColor, BOOL& bOverride, COLORREF& crColor)
  69. {
  70.     bOverride = pLoColor != NULL;
  71.     if( bOverride ){
  72.         crColor = WFE_LO2COLORREF( pLoColor, LO_COLOR_BG );
  73.     } else {
  74.         crColor = DEFAULT_COLORREF;
  75.     }
  76. }
  77.  
  78. #define ED_PIXELS  0
  79. #define ED_PERCENT 1
  80.  
  81. void UpdateWidthAndHeight(CDialog* pPage, int iWidth, int iHeight)
  82. {
  83.     char szBuf[16];
  84.     wsprintf(szBuf, "%d", iWidth);
  85.     pPage->GetDlgItem(IDC_WIDTH)->SetWindowText(szBuf);
  86.  
  87.     wsprintf(szBuf, "%d", iHeight);
  88.     pPage->GetDlgItem(IDC_HEIGHT)->SetWindowText(szBuf);
  89. }
  90.  
  91. BOOL ValidateWidthAndHeight(CDialog* pPage, 
  92.                             int* iWidth, int* iHeight,
  93.                             int iWidthType, int iHeightType)
  94. {
  95.     char szMessage[256];
  96.     CEdit* pWidthControl = (CEdit*)(pPage->GetDlgItem(IDC_WIDTH));
  97.     CEdit* pHeightControl = (CEdit*)(pPage->GetDlgItem(IDC_HEIGHT));
  98.     ASSERT (pWidthControl);
  99.     ASSERT (pHeightControl);
  100.     char szWidth[16] = "";
  101.     char szHeight[16] = "";
  102.     char *szEndWidth;
  103.     char *szEndHeight;
  104.     pWidthControl->GetWindowText(szWidth, 15);
  105.     pHeightControl->GetWindowText(szHeight, 15);
  106.     
  107.     int width = (int)strtol( szWidth, &szEndWidth, 10 );
  108.     int height = (int)strtol( szHeight, &szEndHeight, 10 );
  109.  
  110.     int iMaxWidth = (iWidthType == ED_PERCENT) ? 100 : MAX_TABLE_PIXELS;
  111.     int iMaxHeight = (iHeightType == ED_PERCENT) ? 100 : MAX_TABLE_PIXELS;;
  112.     
  113.     // If we have a checkbox to use width/height, validate range only if it is checked
  114.     // Bad conversion if end pointer isn't at terminal null;
  115.     BOOL bHaveWidthCheck = pPage->GetDlgItem(IDC_OVERRIDE_WIDTH) && 
  116.                            ((CButton*)pPage->GetDlgItem(IDC_OVERRIDE_WIDTH))->GetCheck();
  117.     BOOL bHaveHeightCheck = pPage->GetDlgItem(IDC_OVERRIDE_HEIGHT) && 
  118.                             ((CButton*)pPage->GetDlgItem(IDC_OVERRIDE_HEIGHT))->GetCheck();
  119.     
  120.     // Minimum value is always 1
  121.     BOOL bBadWidth = bHaveWidthCheck && 
  122.                      ( (width < 1  || width > iMaxWidth) || *szEndWidth != '\0');
  123.     BOOL bBadHeight = bHaveHeightCheck && 
  124.                       ( (height< 1  || height > iMaxHeight) || *szEndHeight != '\0');
  125.     
  126.     if( bBadWidth || bBadHeight ){
  127.         // Note: We only show 1 error at a time, so allways check Width error first
  128.  
  129.         // Construct a string showing correct range
  130.         wsprintf( szMessage, szLoadString(IDS_INTEGER_RANGE_ERROR), 1,
  131.                   bBadWidth ? iMaxWidth : iMaxHeight );
  132.  
  133.         // Notify user with similar message to the DDV_ validation system
  134.         pPage->MessageBox(szMessage, szLoadString(AFX_IDS_APP_TITLE), MB_ICONEXCLAMATION | MB_OK);
  135.         
  136.         // Put focus in the offending control
  137.         // And select all text, just like DDV functions
  138.         if( bBadWidth ){
  139.             pWidthControl->SetFocus();
  140.             pWidthControl->SetSel(0, -1, TRUE);
  141.         } else {
  142.             pHeightControl->SetFocus();
  143.             pHeightControl->SetSel(0, -1, TRUE);
  144.         }
  145.         return FALSE;
  146.     }
  147.     // Save values if they are good
  148.     if( width > 0 ){
  149.         *iWidth = width;
  150.     }
  151.     if( height > 0 ){
  152.         *iHeight = height;
  153.     }
  154.     return TRUE;
  155. }
  156.  
  157. void SetTableCaption(MWContext * pMWContext, int iCaptionIndex)
  158. {
  159.     // Try to get existing caption data
  160.     EDT_TableCaptionData* pTableCaptionData = EDT_GetTableCaptionData(pMWContext);
  161.     // NOTE: We shouldn't set insert point to the caption when it is inserted!
  162.     //  so don't use that as test for existing caption
  163.     BOOL bAlreadyHaveCaption = pTableCaptionData != NULL;
  164.     
  165.     if ( iCaptionIndex > 0 ) {
  166.         if ( !bAlreadyHaveCaption ) {
  167.             // Create new caption
  168.             pTableCaptionData = EDT_NewTableCaptionData();
  169.         }
  170.         if ( pTableCaptionData ) {
  171.             pTableCaptionData->align = (iCaptionIndex == 1 ? ED_ALIGN_ABSTOP : ED_ALIGN_ABSBOTTOM);
  172.  
  173.             if( bAlreadyHaveCaption ){
  174.                 // Change existing caption data
  175.                 EDT_SetTableCaptionData(pMWContext, pTableCaptionData);
  176.             } else {
  177.                 // Insert a new caption
  178.                 EDT_InsertTableCaption(pMWContext, pTableCaptionData);
  179.             }
  180.             EDT_FreeTableCaptionData(pTableCaptionData);
  181.         }
  182.     } else if ( bAlreadyHaveCaption ) {
  183.         // We have a caption but user changed to "none" so remove it
  184.         EDT_DeleteTableCaption(pMWContext);
  185.     }
  186. }
  187.  
  188. int GetTableAlign(EDT_TableData * pTableData)
  189. {
  190.     int iAlign = 0; // Default = Left align
  191.     if( pTableData ){
  192.         switch ( pTableData->align){
  193.             case ED_ALIGN_CENTER:
  194.             case ED_ALIGN_ABSCENTER:
  195.                 iAlign = 1;
  196.                 break;
  197.             case ED_ALIGN_RIGHT:
  198.                 iAlign = 2;
  199.                 break;
  200.         }
  201.     }
  202.     return iAlign;
  203. }
  204.  
  205. void SetTableAlign(EDT_TableData * pTableData, int iAlign)
  206. {
  207.     if( pTableData ){
  208.         switch ( iAlign ){
  209.             case 1:
  210.                 pTableData->align = ED_ALIGN_ABSCENTER;
  211.                 break;
  212.             case 2:
  213.                 pTableData->align = ED_ALIGN_RIGHT;
  214.                 break;
  215.             default:       // 0 or -1
  216.                 pTableData->align = ED_ALIGN_LEFT;
  217.         }
  218.     }
  219. }
  220.  
  221. //////////////////////////////////////////////////////
  222. //
  223. // Property pages for Table and Cell Table properties
  224. //
  225. /////////////////////////////////////////////////////////////////////
  226. CTablePage::CTablePage(CWnd *pParent, MWContext * pMWContext,
  227.                        CEditorResourceSwitcher * pResourceSwitcher,
  228.                        EDT_TableData * pTableData)
  229.            : CNetscapePropertyPage(CTablePage::IDD),
  230.              m_bActivated(0),
  231.              m_pMWContext(pMWContext),
  232.              m_pResourceSwitcher(pResourceSwitcher),
  233.              m_pTableData(pTableData),
  234.              m_bCustomColor(0),
  235.              m_crColor(DEFAULT_COLORREF),
  236.              m_iParentWidth(0),
  237.              m_iParentHeight(0),
  238.              m_bInternalChangeEditbox(0)
  239. {
  240.     ASSERT(pMWContext);
  241.     ASSERT(pTableData);
  242.     //{{AFX_DATA_INIT(CPage)
  243.     m_iRows = 0;
  244.     m_iColumns = 0;
  245.     m_iAlign = -1;
  246.     m_iCaption = 0;
  247.     m_iBorderWidth = 0;
  248.     m_iCellPadding = 0;
  249.     m_iCellSpacing = 0;
  250.     m_bColumnHeader = FALSE;
  251.     m_bUseColor = FALSE;
  252.     m_bUseHeight = FALSE;
  253.     m_bUseWidth = FALSE;
  254.     m_iHeight = 1;
  255.     m_iHeightType = 0;
  256.     m_iWidthType = 0;
  257.     m_bRowHeader = FALSE;
  258.     m_iWidth = 1;
  259.     m_bUseCols = TRUE;
  260.     m_csBackgroundImage = _T("");
  261.     m_bNoSave = 0;
  262.     m_bBorderWidthDefined = FALSE;
  263.     //}}AFX_DATA_INIT
  264.  
  265. #ifdef XP_WIN32
  266.     // Set the hInstance so we get template from editor's resource DLL
  267.     m_psp.hInstance = AfxGetResourceHandle();
  268. #endif
  269. }
  270.  
  271.  
  272. void CTablePage::DoDataExchange(CDataExchange* pDX)
  273. {
  274.     CPropertyPage::DoDataExchange(pDX);
  275.     //{{AFX_DATA_MAP(CTablePage)
  276.     DDX_Text(pDX, IDC_ROWS, m_iRows);
  277.     DDV_MinMaxInt(pDX, m_iRows, 1, MAX_TABLE_ROWS);
  278.     DDX_Text(pDX, IDC_COLUMNS, m_iColumns);
  279.     DDV_MinMaxInt(pDX, m_iColumns, 1, MAX_TABLE_COLUMNS);
  280.     DDX_CBIndex(pDX, IDC_TABLE_ALIGN, m_iAlign);
  281.     DDX_CBIndex(pDX, IDC_TABLE_CAPTION, m_iCaption);
  282.     DDX_Text(pDX, IDC_BORDER, m_iBorderWidth);
  283.     DDV_MinMaxInt(pDX, m_iBorderWidth, 0, MAX_TABLE_PIXELS);
  284.     DDX_Text(pDX, IDC_CELL_PADDING, m_iCellPadding);
  285.     DDV_MinMaxInt(pDX, m_iCellPadding, 0, MAX_TABLE_PIXELS);
  286.     DDX_Text(pDX, IDC_CELL_SPACING, m_iCellSpacing);
  287.     DDV_MinMaxInt(pDX, m_iCellSpacing, 0, MAX_TABLE_PIXELS);
  288.     DDX_Check(pDX, IDC_OVERRIDE_COLOR, m_bUseColor);
  289.     DDX_Check(pDX, IDC_OVERRIDE_HEIGHT, m_bUseHeight);
  290.     DDX_Check(pDX, IDC_OVERRIDE_WIDTH, m_bUseWidth);
  291.     DDX_CBIndex(pDX, IDC_WIDTH_PIX_OR_PERCENT, m_iWidthType);
  292.     DDX_CBIndex(pDX, IDC_HEIGHT_PIX_OR_PERCENT, m_iHeightType);
  293.     DDX_Check(pDX, IDC_USE_COLS, m_bUseCols);
  294.     DDX_Text(pDX, IDC_BKGRND_IMAGE, m_csBackgroundImage);
  295.     DDX_Check(pDX, IDC_NO_SAVE_IMAGE, m_bNoSave);
  296.     DDX_Check(pDX, IDC_USE_BORDER, m_bBorderWidthDefined);
  297.     //}}AFX_DATA_MAP
  298. }
  299.  
  300. BEGIN_MESSAGE_MAP(CTablePage, CNetscapePropertyPage)
  301.     //{{AFX_MSG_MAP(CTablePage)
  302.     ON_EN_CHANGE(IDC_ROWS, EnableApplyButton)
  303.     ON_EN_CHANGE(IDC_COLUMNS, EnableApplyButton)
  304.     ON_EN_CHANGE(IDC_ROWS, EnableApplyButton)
  305.     ON_EN_CHANGE(IDC_COLUMNS, EnableApplyButton)
  306.     ON_EN_CHANGE(IDC_CELL_SPACING, EnableApplyButton)
  307.     ON_EN_CHANGE(IDC_CELL_PADDING, EnableApplyButton)
  308.     ON_CBN_SELCHANGE(IDC_TABLE_ALIGN, EnableApplyButton)
  309.     ON_EN_CHANGE(IDC_TABLE_CAPTION, EnableApplyButton)
  310.     ON_BN_CLICKED(IDC_OVERRIDE_WIDTH, EnableApplyButton)
  311.     ON_BN_CLICKED(IDC_USE_BORDER, EnableApplyButton)
  312.     ON_EN_CHANGE(IDC_BORDER, OnChangeBorder)
  313.     ON_EN_CHANGE(IDC_WIDTH, OnChangeWidth)
  314.     ON_CBN_SELCHANGE(IDC_WIDTH_PIX_OR_PERCENT, OnChangeWidthType)
  315.     ON_BN_CLICKED(IDC_OVERRIDE_HEIGHT, EnableApplyButton)
  316.     ON_EN_CHANGE(IDC_HEIGHT, OnChangeHeight)
  317.     ON_CBN_SELCHANGE(IDC_HEIGHT_PIX_OR_PERCENT, OnChangeHeightType)
  318.     ON_BN_CLICKED(IDC_OVERRIDE_COLOR, OnOverrideColor)
  319.     ON_BN_CLICKED(IDC_CHOOSE_COLOR, OnChooseColor)
  320.     ON_WM_PAINT()
  321.     ON_BN_CLICKED(IDC_EXTRA_HTML, OnExtraHTML)
  322.     ON_BN_CLICKED(IDC_USE_COLS, EnableApplyButton)
  323.     ON_BN_CLICKED(IDC_BKGRND_USE_IMAGE, OnUseBkgrndImage)
  324.     ON_EN_CHANGE(IDC_BKGRND_IMAGE, OnChangeBkgrndImage)
  325.     ON_BN_CLICKED(IDC_CHOOSE_BACKGROUND, OnChooseBkgrndImage)
  326.     ON_BN_CLICKED(IDC_NO_SAVE_IMAGE, OnNoSave)
  327.     //}}AFX_MSG_MAP
  328. END_MESSAGE_MAP()
  329.  
  330. BOOL CTablePage::OnSetActive() 
  331. {
  332.     if(m_pResourceSwitcher && !m_bActivated)
  333.     {
  334.         // We must be sure we have switched
  335.         //  the first time here - before dialog creation
  336.         m_pResourceSwitcher->switchResources();
  337.     }
  338.     if(!CPropertyPage::OnSetActive())
  339.         return(FALSE);
  340.  
  341.     if(m_bActivated)
  342.         return(TRUE);
  343.  
  344.     m_bActivated = TRUE;
  345.  
  346.     // Switch back to EXE's resources
  347.     if( m_pResourceSwitcher )
  348.         m_pResourceSwitcher->Reset();
  349.  
  350.     if( !m_ColorButton.Subclass(this, IDC_CHOOSE_COLOR, &m_crColor) )
  351.         return FALSE;
  352.  
  353.     ((CEdit*)GetDlgItem(IDC_COLUMNS))->LimitText(3);
  354.     ((CEdit*)GetDlgItem(IDC_ROWS))->LimitText(3);
  355.     ((CEdit*)GetDlgItem(IDC_BORDER))->LimitText(5);
  356.     ((CEdit*)GetDlgItem(IDC_CELL_PADDING))->LimitText(5);
  357.     ((CEdit*)GetDlgItem(IDC_CELL_SPACING))->LimitText(5);
  358.     ((CEdit*)GetDlgItem(IDC_HEIGHT))->LimitText(5);
  359.     ((CEdit*)GetDlgItem(IDC_WIDTH))->LimitText(5);
  360.  
  361.     m_iRows = m_pTableData->iRows;
  362.     m_iColumns =  m_pTableData->iColumns;
  363.     m_bBorderWidthDefined = m_pTableData->bBorderWidthDefined;
  364.     m_iBorderWidth = CASTINT(m_pTableData->iBorderWidth);
  365.     m_iCellSpacing = CASTINT(m_pTableData->iCellSpacing);
  366.     m_iCellPadding = CASTINT(m_pTableData->iCellPadding);
  367.     m_iWidth = CASTINT(m_pTableData->iWidth);
  368.     m_iHeight = CASTINT(m_pTableData->iHeight);
  369.     m_iWidthType = m_pTableData->bWidthPercent ? ED_PERCENT : ED_PIXELS;
  370.     m_iHeightType = m_pTableData->bHeightPercent ? ED_PERCENT : ED_PIXELS;
  371.     m_iAlign = GetTableAlign(m_pTableData);
  372.     m_bUseCols = m_pTableData->bUseCols;
  373.  
  374.     GetColorHelper(m_pTableData->pColorBackground, m_bUseColor, m_crColor);
  375.  
  376.     // Fill comboboxes
  377.     CComboBox *pCombo = (CComboBox*)GetDlgItem(IDC_TABLE_ALIGN);
  378.     pCombo->AddString(szLoadString(IDS_LEFT));
  379.     pCombo->AddString(szLoadString(IDS_CENTER));
  380.     pCombo->AddString(szLoadString(IDS_RIGHT));
  381.  
  382.     pCombo = (CComboBox*)GetDlgItem(IDC_TABLE_CAPTION);
  383.     pCombo->AddString(szLoadString(IDS_CAPTION_NONE));
  384.     pCombo->AddString(szLoadString(IDS_CAPTION_ABOVE));
  385.     pCombo->AddString(szLoadString(IDS_CAPTION_BELOW));
  386.  
  387.     EDT_TableCaptionData* pTableCaptionData = EDT_GetTableCaptionData(m_pMWContext);
  388.     if ( pTableCaptionData )
  389.     {
  390.         m_iCaption = pTableCaptionData->align == ED_ALIGN_ABSTOP ? 1 : 2;
  391.         EDT_FreeTableCaptionData(pTableCaptionData);
  392.     }
  393.     
  394.     // Initialize string: use "% of window" if not in table, 
  395.     // or "% of parent cell" if we're in a cell
  396.     pCombo = (CComboBox*)GetDlgItem(IDC_HEIGHT_PIX_OR_PERCENT);
  397.     char *pPercent = szLoadString(CASTUINT(EDT_IsInsertPointInNestedTable(m_pMWContext) ? IDS_PERCENT_PARENT_CELL : IDS_PERCENT_WINDOW));
  398.     pCombo->AddString(szLoadString(IDS_PIXELS));
  399.     pCombo->AddString(pPercent);
  400.  
  401.     pCombo = (CComboBox*)GetDlgItem(IDC_WIDTH_PIX_OR_PERCENT);
  402.     pCombo->AddString(szLoadString(IDS_PIXELS));
  403.     pCombo->AddString(pPercent);
  404.         
  405.     // Get background image and set checkbox
  406.     m_csBackgroundImage = m_pTableData->pBackgroundImage;
  407.     if ( !m_csBackgroundImage.IsEmpty() )
  408.     {
  409.         ((CButton*)GetDlgItem(IDC_BKGRND_USE_IMAGE))->SetCheck(1);
  410.         m_bUseColor = FALSE;
  411.         ((CButton*)GetDlgItem(IDC_OVERRIDE_COLOR))->SetCheck(0);
  412.     }
  413.     // Disable NoSaveImage checkbox if using color
  414.     if( m_bUseColor )
  415.         GetDlgItem(IDC_NO_SAVE_IMAGE)->EnableWindow(FALSE);
  416.  
  417.     // Flag to leave image at original location and not save with page
  418.     m_bNoSave = m_pTableData->bBackgroundNoSave;
  419.  
  420.     // Get size of parent to convert % values to pixels and vice versa
  421.     // FALSE = get current table's "parent" data (current view or cell if nested table)
  422.     // Use to convert pixels to "% of parent" 
  423.     EDT_GetTableParentSize(m_pMWContext, FALSE, &m_iParentWidth, &m_iParentHeight);
  424.  
  425.     // We don't use DDX with these so we don't get "not-integer" error messages
  426.     // Set flag to prevent changing the associated checkbox
  427.     m_bInternalChangeEditbox = TRUE;
  428.     UpdateWidthAndHeight(this, m_iWidth, m_iHeight);
  429.     m_bInternalChangeEditbox = FALSE;
  430.  
  431.     // Send data to controls
  432.     UpdateData(FALSE);
  433.  
  434.     // Clear data-modified flag
  435.     SetModified(FALSE);
  436.  
  437.     return(TRUE);
  438. }
  439.  
  440. BOOL CTablePage::OnKillActive()
  441. {
  442.     // never visited this page or no change -- don't bother
  443.     if(!m_bActivated ||
  444.        !IS_APPLY_ENABLED(this))
  445.     {
  446.         return TRUE;
  447.     }
  448.     if ( !UpdateData(TRUE) ||
  449.          !ValidateWidthAndHeight(this, &m_iWidth, &m_iHeight, m_iWidthType, m_iHeightType) )
  450.     {
  451.         return FALSE;
  452.     }
  453.     if ( !m_csBackgroundImage.IsEmpty() )
  454.     {
  455.         if ( m_bImageChanged && !m_bValidImage )
  456.         {
  457.             if( ((CButton*)GetDlgItem(IDC_BKGRND_USE_IMAGE))->GetCheck() &&
  458.                 !wfe_ValidateImage( m_pMWContext, m_csBackgroundImage, FALSE /*TRUE*/  ) )
  459.             {
  460.                 ((CButton*)GetDlgItem(IDC_BKGRND_USE_IMAGE))->SetCheck(0);
  461.                 GetDlgItem(IDC_NO_SAVE_IMAGE)->EnableWindow(FALSE);
  462.                 return FALSE;
  463.             }
  464.             GetDlgItem(IDC_NO_SAVE_IMAGE)->EnableWindow(TRUE);
  465.             // Send changed image back to editbox in case this is Apply usage
  466.             UpdateData(FALSE);
  467.         }
  468.     }
  469.     if( ((CButton*)GetDlgItem(IDC_BKGRND_USE_IMAGE))->GetCheck() &&
  470.         !m_csBackgroundImage.IsEmpty() )
  471.     {
  472.         wfe_ValidateImage( m_pMWContext, m_csBackgroundImage );
  473.         int iLastDot = m_csBackgroundImage.ReverseFind('.');
  474.         CString csExt;
  475.         if(iLastDot > 0)
  476.             csExt= m_csBackgroundImage.Mid(iLastDot);
  477.  
  478.         //we must check to see if file is a bmp!
  479.         if (0 == csExt.CompareNoCase(".bmp"))
  480.         {
  481.             char *t_outputfilename=wfe_ConvertImage(m_csBackgroundImage.GetBuffer(0),(void *)this,m_pMWContext);
  482.             if (t_outputfilename)
  483.             {
  484.                 m_csBackgroundImage=t_outputfilename;
  485.                 wfe_ValidateImage( m_pMWContext, m_csBackgroundImage );
  486.                 XP_FREE(t_outputfilename);
  487.                 UpdateData(FALSE);//we need to update m_csImage!
  488.             }
  489.             else 
  490.                 return FALSE;
  491.         }
  492.     }
  493.  
  494.     return TRUE;
  495. }
  496.  
  497. void CTablePage::OnHelp() 
  498. {
  499.     NetHelp(HELP_TABLE_PROPS_TABLE);
  500. }
  501.  
  502. void CTablePage::OnOK() 
  503. {
  504.     // never visited this page or no change -- don't bother
  505.     if(!m_bActivated ||
  506.        !IS_APPLY_ENABLED(this)){
  507.         return;
  508.     }
  509.  
  510.     EDT_BeginBatchChanges(m_pMWContext);
  511.  
  512.     // Save background image
  513.     if ( m_pTableData->pBackgroundImage )
  514.     {
  515.         XP_FREE( m_pTableData->pBackgroundImage );
  516.         m_pTableData->pBackgroundImage = NULL;
  517.     }
  518.  
  519.     if( ((CButton*)GetDlgItem(IDC_BKGRND_USE_IMAGE))->GetCheck() &&
  520.         !m_csBackgroundImage.IsEmpty() ){
  521.         m_pTableData->pBackgroundImage = XP_STRDUP(m_csBackgroundImage);
  522.         // Save state of flag from checkbox
  523.         m_pTableData->bBackgroundNoSave = m_bNoSave;
  524.     }
  525.  
  526.     m_pTableData->iRows = m_iRows;
  527.     m_pTableData->iColumns = m_iColumns;
  528.     m_pTableData->bBorderWidthDefined = m_bBorderWidthDefined;
  529.     m_pTableData->iBorderWidth = m_iBorderWidth;
  530.     m_pTableData->iCellSpacing = m_iCellSpacing;
  531.     m_pTableData->iCellPadding = m_iCellPadding;
  532.     m_pTableData->bWidthDefined = m_bUseWidth;
  533.     m_pTableData->bWidthPercent = m_iWidthType == ED_PERCENT;
  534.     m_pTableData->iWidth = m_iWidth;
  535.     m_pTableData->bHeightDefined = m_bUseHeight;
  536.     m_pTableData->bHeightPercent = m_iHeightType == ED_PERCENT;
  537.     m_pTableData->iHeight = m_iHeight;
  538.     m_pTableData->bUseCols = m_bUseCols;
  539.  
  540.     SetTableAlign(m_pTableData, m_iAlign);
  541.     SetColorHelper(m_bUseColor, m_crColor, &m_pTableData->pColorBackground);
  542.  
  543.     EDT_SetTableData(m_pMWContext, m_pTableData);
  544.     // Note: Caller must free m_pTableData
  545.  
  546.     // OK, we need to insert or remove a caption, as nescessary.
  547.     SetTableCaption(m_pMWContext, m_iCaption);
  548.  
  549.     OkToClose(); // CancelToClose() doesn't work!
  550.     EDT_EndBatchChanges(m_pMWContext);
  551.  
  552.     CPropertyPage::OnOK();
  553.  
  554.     // These may be different as a result of Relayout during EDT_SetTableData()
  555.     //  (Backend fixes up size data to reflect layout algorithms)
  556.     m_iWidth = m_pTableData->iWidth;
  557.     m_iHeight = m_pTableData->iHeight;
  558.  
  559.     // Get possibly new size of parent because of Relayout
  560.     EDT_GetTableParentSize(m_pMWContext, FALSE, &m_iParentWidth, &m_iParentHeight);
  561.  
  562.     // We don't use DDX with these so we don't get "not-integer" error messages
  563.     // Set flag to prevent changing the associated checkbox
  564.     m_bInternalChangeEditbox = TRUE;
  565.     UpdateWidthAndHeight(this, m_iWidth, m_iHeight);
  566.     m_bInternalChangeEditbox = FALSE;
  567. }
  568.  
  569. void CTablePage::OnExtraHTML()
  570. {
  571.     CExtraHTMLDlg dlg(this, &m_pTableData->pExtra, IDS_TABLE_TAG);
  572.     if( IDOK == dlg.DoModal() )
  573.         SetModified(TRUE);
  574. }
  575.  
  576. // Shared message handler for controls that
  577. //  only need to change Apply state
  578. void CTablePage::EnableApplyButton()
  579. {
  580.     SetModified(TRUE);
  581. }
  582.  
  583. void CTablePage::OnChangeBorder()
  584. {
  585.     ((CButton*)GetDlgItem(IDC_USE_BORDER))->SetCheck(1);
  586.     m_bBorderWidthDefined = TRUE;
  587.     SetModified(TRUE);
  588. }
  589.  
  590. void CTablePage::OnChangeWidth()
  591. {
  592.     if( !m_bInternalChangeEditbox )
  593.     {
  594.         SetModified(TRUE);
  595.         m_bUseWidth = TRUE;
  596.         ((CButton*)GetDlgItem(IDC_OVERRIDE_WIDTH))->SetCheck(1);
  597.     }
  598. }
  599.  
  600. void CTablePage::OnChangeWidthType()
  601. {
  602.     // See if type has changed and we need to convert
  603.     //   to opposite type (pixels <-> percent of parent)
  604.     int iWidthType = ((CComboBox*)GetDlgItem(IDC_WIDTH_PIX_OR_PERCENT))->GetCurSel();
  605.     if( iWidthType != m_iWidthType )
  606.     {
  607.         // Get current data from edit box before converting
  608.         // Note that validation uses NEW width type 
  609.         if( ValidateWidthAndHeight(this, &m_iWidth, &m_iHeight, iWidthType, m_iHeightType) )
  610.         {
  611.             if( iWidthType )
  612.                 // Convert previous from % to pixels
  613.                 m_iWidth = (m_iWidth * m_iParentWidth ) / 100;
  614.             else 
  615.                 // Convert previous value from pixels to %
  616.                 m_iWidth = (m_iWidth * 100) / m_iParentWidth;
  617.  
  618.             // This will trigger OnChange for width,
  619.             //  which will set the IDC_OVERRIDE_WIDTH checkbox
  620.             UpdateWidthAndHeight(this, m_iWidth, m_iHeight);
  621.             SetModified(TRUE);
  622.         }
  623.         m_iWidthType = iWidthType;
  624.     }
  625. }
  626.  
  627.  
  628. void CTablePage::OnChangeHeight()
  629. {
  630.     if( !m_bInternalChangeEditbox )
  631.     {
  632.         SetModified(TRUE);
  633.         m_bUseHeight = TRUE;
  634.         ((CButton*)GetDlgItem(IDC_OVERRIDE_HEIGHT))->SetCheck(1);
  635.     }
  636. }
  637.  
  638. void CTablePage::OnChangeHeightType()
  639. {
  640.     // See if type has changed and we need to convert
  641.     //   to opposite type (pixels <-> percent of parent)
  642.     int iHeightType = ((CComboBox*)GetDlgItem(IDC_HEIGHT_PIX_OR_PERCENT))->GetCurSel();
  643.     if( iHeightType != m_iHeightType )
  644.     {
  645.         // Get current data from edit box before converting
  646.         // Note that validation uses NEW height type 
  647.         if( ValidateWidthAndHeight(this, &m_iWidth, &m_iHeight, m_iWidthType, iHeightType) )
  648.         {
  649.             if( iHeightType )
  650.                 // Convert previous from % to pixels
  651.                 m_iHeight = (m_iHeight * m_iParentHeight ) / 100;
  652.             else 
  653.                 // Convert previous value from pixels to %
  654.                 m_iHeight = (m_iHeight * 100) / m_iParentHeight;
  655.  
  656.             // This will trigger OnChange for height,
  657.             //  which will set the IDC_OVERRIDE_HEIGHT checkbox
  658.             UpdateWidthAndHeight(this, m_iWidth, m_iHeight);
  659.             SetModified(TRUE);
  660.         }
  661.         m_iHeightType = iHeightType;
  662.     }
  663. }
  664.  
  665. void CTablePage::OnOverrideColor() 
  666. {
  667.     m_bUseColor = ((CButton*)GetDlgItem(IDC_OVERRIDE_COLOR))->GetCheck();
  668.     SetModified(TRUE);
  669. }
  670.  
  671. void CTablePage::OnChooseColor() 
  672. {
  673.     // Get the combobox location so we popup new dialog just under it
  674.     RECT rect;
  675.     GetDlgItem(IDC_CHOOSE_COLOR)->GetWindowRect(&rect);
  676.  
  677.     CColorPicker dlg(this, m_pMWContext, m_crColor, BACKGROUND_COLORREF, 0, &rect);
  678.  
  679.     COLORREF crNew = dlg.GetColor();
  680.     if( crNew != CANCEL_COLORREF )
  681.     {
  682.         m_crColor = crNew;
  683.         if(m_crColor == DEFAULT_COLORREF){
  684.             m_crColor = prefInfo.m_rgbBackgroundColor;
  685.         }
  686.         m_bUseColor = TRUE;
  687.         ((CButton*)GetDlgItem(IDC_OVERRIDE_COLOR))->SetCheck(m_bUseColor);
  688.         m_ColorButton.Update();
  689.         SetModified(TRUE);
  690.     }
  691. }
  692.  
  693. void CTablePage::OnUseBkgrndImage() 
  694. {
  695.     int iUseImageBackground = ((CButton*)GetDlgItem(IDC_BKGRND_USE_IMAGE))->GetCheck();;
  696.     SetModified(TRUE);
  697.     if( iUseImageBackground )
  698.     {
  699.         // User decided to use the image, so do trigger validation
  700.         if( !m_csBackgroundImage.IsEmpty() && 
  701.             wfe_ValidateImage( m_pMWContext, m_csBackgroundImage, FALSE /*TRUE*/  ) )
  702.         {
  703.             ((CButton*)GetDlgItem(IDC_BKGRND_USE_IMAGE))->SetCheck(1);
  704.         } else {
  705.             GetDlgItem(IDC_BKGRND_IMAGE)->SetFocus();
  706.         }
  707.         m_bValidImage = TRUE;
  708.     }
  709.     GetDlgItem(IDC_NO_SAVE_IMAGE)->EnableWindow(iUseImageBackground);
  710. }
  711.  
  712. void CTablePage::OnChooseBkgrndImage() 
  713. {
  714.     UpdateData(TRUE);
  715.     char * szFilename = wfe_GetExistingImageFileName(this->m_hWnd, 
  716.                                          szLoadString(IDS_SELECT_IMAGE), TRUE);
  717.     if ( szFilename == NULL )
  718.         return;
  719.  
  720.     m_csBackgroundImage = szFilename;
  721.     if( wfe_ValidateImage( m_pMWContext, m_csBackgroundImage, FALSE /*TRUE*/  ) )
  722.     {
  723.         ((CButton*)GetDlgItem(IDC_BKGRND_USE_IMAGE))->SetCheck(1);
  724.         GetDlgItem(IDC_NO_SAVE_IMAGE)->EnableWindow(TRUE);
  725.     } else {
  726.         ((CButton*)GetDlgItem(IDC_BKGRND_USE_IMAGE))->SetCheck(0);
  727.         GetDlgItem(IDC_NO_SAVE_IMAGE)->EnableWindow(FALSE);
  728.     }
  729.  
  730.     // Send new name to editbox
  731.     UpdateData(FALSE);
  732.  
  733.     XP_FREE( szFilename );
  734.     m_bValidImage = TRUE;
  735.     m_bImageChanged = FALSE;
  736.     SetModified(TRUE);
  737. }
  738.  
  739. void CTablePage::OnNoSave() 
  740. {
  741.     SetModified(TRUE);
  742. }
  743.  
  744. void CTablePage::OnChangeBkgrndImage() 
  745. {
  746.     // Set flags to trigger validation
  747.     m_bValidImage = FALSE;
  748.     m_bImageChanged = TRUE;
  749.     
  750.     UpdateData(TRUE);
  751.     CString csTemp = m_csBackgroundImage;
  752.     csTemp.TrimLeft();
  753.     csTemp.TrimRight();
  754.  
  755.     // Set checkbox if there are any characters, clear if empty
  756.     ((CButton*)GetDlgItem(IDC_BKGRND_USE_IMAGE))->SetCheck(!csTemp.IsEmpty());
  757.     if(!csTemp.IsEmpty())
  758.         GetDlgItem(IDC_NO_SAVE_IMAGE)->EnableWindow(TRUE);
  759.  
  760.     SetModified(TRUE);
  761. }
  762.  
  763. /////////////////////////////////////////////////////////////////
  764. CTableCellPage::CTableCellPage(CWnd *pParent, MWContext * pMWContext,
  765.                                CEditorResourceSwitcher * pResourceSwitcher,
  766.                                EDT_TableCellData * pCellData,
  767.                                UINT nIDCaption )
  768.     : CNetscapePropertyPage(CTableCellPage::IDD, nIDCaption),
  769.       m_bActivated(0),
  770.       m_pMWContext(pMWContext),
  771.       m_pResourceSwitcher(pResourceSwitcher),
  772.       m_pCellData(pCellData),
  773.       m_bCustomColor(0),
  774.       m_crColor(DEFAULT_COLORREF),
  775.       m_iParentWidth(0),
  776.       m_iParentHeight(0),
  777.       m_bInternalChangeEditbox(0)
  778. {
  779.     ASSERT(pMWContext);
  780.     ASSERT(pCellData);
  781.     //{{AFX_DATA_INIT(CPage)
  782.     m_iAlign = -1;
  783.     m_iVAlign = -1;
  784.     m_iColumnSpan = 0;
  785.     m_iUseColor = 0;
  786.     m_iUseHeight = 0;
  787.     m_iUseWidth = 0;
  788.     m_iHeader = FALSE;
  789.     m_iHeight = 1;
  790.     m_iHeightType = 0;
  791.     m_iWidthType = 0;
  792.     m_iRowSpan = 0;
  793.     m_iWidth = 1;
  794.     m_iNoWrap = 1;
  795.     m_csBackgroundImage = _T("");
  796.     m_bNoSave = 0;
  797.     //}}AFX_DATA_INIT
  798.  
  799. #ifdef XP_WIN32
  800.     // Set the hInstance so we get template from editor's resource DLL
  801.     m_psp.hInstance = AfxGetResourceHandle();
  802. #endif
  803. }
  804.  
  805. void CTableCellPage::DoDataExchange(CDataExchange* pDX)
  806. {
  807.     CPropertyPage::DoDataExchange(pDX);
  808.     //{{AFX_DATA_MAP(CTableCellPage)
  809.     DDX_Text(pDX, IDC_ROWSPAN, m_iRowSpan);
  810.     DDV_MinMaxInt(pDX, m_iRowSpan, 1, 100);
  811.     DDX_Text(pDX, IDC_COLSPAN, m_iColumnSpan);
  812.     DDV_MinMaxInt(pDX, m_iColumnSpan, 1, 100);
  813.     DDX_CBIndex(pDX, IDC_TABLE_CELL_ALIGN, m_iAlign);
  814.     DDX_CBIndex(pDX, IDC_TABLE_CELL_VALIGN, m_iVAlign);
  815.     DDX_Check(pDX, IDC_OVERRIDE_COLOR, m_iUseColor);
  816.     DDX_Check(pDX, IDC_OVERRIDE_HEIGHT, m_iUseHeight);
  817.     DDX_Check(pDX, IDC_OVERRIDE_WIDTH, m_iUseWidth);
  818.     DDX_Check(pDX, IDC_HEADER, m_iHeader);
  819.     DDX_Check(pDX, IDC_WRAP, m_iNoWrap);
  820.     DDX_CBIndex(pDX, IDC_WIDTH_PIX_OR_PERCENT, m_iWidthType);
  821.     DDX_CBIndex(pDX, IDC_HEIGHT_PIX_OR_PERCENT, m_iHeightType);
  822.     DDX_Text(pDX, IDC_BKGRND_IMAGE, m_csBackgroundImage);
  823.     DDX_Check(pDX, IDC_NO_SAVE_IMAGE, m_bNoSave);
  824. //}}AFX_DATA_MAP
  825. }
  826.  
  827. BEGIN_MESSAGE_MAP(CTableCellPage, CNetscapePropertyPage)
  828.     //{{AFX_MSG_MAP(CTableCellPage)
  829.     ON_EN_CHANGE(IDC_ROWSPAN, EnableApplyButton)
  830.     ON_EN_CHANGE(IDC_COLSPAN, EnableApplyButton)
  831.     ON_BN_CLICKED(IDC_HEADER, EnableApplyButton)
  832.     ON_BN_CLICKED(IDC_WRAP, EnableApplyButton)
  833.     ON_CBN_SELCHANGE(IDC_TABLE_CELL_ALIGN, OnChangeHAlign)
  834.     ON_CBN_SELCHANGE(IDC_TABLE_CELL_VALIGN, OnChangeVAlign)
  835.     ON_BN_CLICKED(IDC_OVERRIDE_WIDTH, EnableApplyButton)
  836.     ON_EN_CHANGE(IDC_WIDTH, OnChangeWidth)
  837.     ON_CBN_SELCHANGE(IDC_WIDTH_PIX_OR_PERCENT, OnChangeWidthType)
  838.     ON_BN_CLICKED(IDC_OVERRIDE_HEIGHT, EnableApplyButton)
  839.     ON_EN_CHANGE(IDC_HEIGHT, OnChangeHeight)
  840.     ON_CBN_SELCHANGE(IDC_HEIGHT_PIX_OR_PERCENT, OnChangeHeightType)
  841.     ON_BN_CLICKED(IDC_OVERRIDE_COLOR, OnOverrideColor)
  842.     ON_BN_CLICKED(IDC_CHOOSE_COLOR, OnChooseColor)
  843.     ON_BN_CLICKED(IDC_EXTRA_HTML, OnExtraHTML)
  844.     ON_BN_CLICKED(IDC_BKGRND_USE_IMAGE, OnUseBkgrndImage)
  845.     ON_EN_CHANGE(IDC_BKGRND_IMAGE, OnChangeBkgrndImage)
  846.     ON_BN_CLICKED(IDC_CHOOSE_BACKGROUND, OnChooseBkgrndImage)
  847.     ON_BN_CLICKED(IDC_NO_SAVE_IMAGE, EnableApplyButton)
  848.     ON_BN_CLICKED(IDC_PREVIOUS, OnPrevious)
  849.     ON_BN_CLICKED(IDC_NEXT, OnNext)
  850.     ON_CBN_SELCHANGE(IDC_TABLE_SELECTION_TYPE, OnChangeSelectionType)
  851.     ON_BN_CLICKED(IDC_INSERT, OnInsert)
  852.     ON_BN_CLICKED(IDC_DELETE, OnDelete)
  853.     //}}AFX_MSG_MAP
  854. END_MESSAGE_MAP()
  855.  
  856. BOOL CTableCellPage::OnSetActive() 
  857. {
  858.     if(m_pResourceSwitcher && !m_bActivated)
  859.     {
  860.         // We must be sure we have switched
  861.         //  the first time here - before dialog creation
  862.         m_pResourceSwitcher->switchResources();
  863.     }
  864.     if(!CPropertyPage::OnSetActive())
  865.         return(FALSE);
  866.  
  867.     if(m_bActivated)
  868.         return(TRUE);
  869.  
  870.     m_bActivated = TRUE;
  871.  
  872.     // Get these strings from the editor resource dll before we switch back
  873.     m_csSingleCell.LoadString(IDS_SINGLE_CELL_CAPTION);
  874.     m_csSelectedCells.LoadString(IDS_SELECTED_CELLS_CAPTION); 
  875.     m_csSelectedRow.LoadString(IDS_SELECTED_ROW_CAPTION);
  876.     m_csSelectedCol.LoadString(IDS_SELECTED_COLUMN_CAPTION);
  877.  
  878.     // Switch back to EXE's resources
  879.     if( m_pResourceSwitcher )
  880.         m_pResourceSwitcher->Reset();
  881.  
  882.     if( !m_ColorButton.Subclass(this, IDC_CHOOSE_COLOR, &m_crColor) )
  883.         return FALSE;
  884.  
  885.     ((CEdit*)GetDlgItem(IDC_ROWSPAN))->LimitText(3);
  886.     ((CEdit*)GetDlgItem(IDC_COLSPAN))->LimitText(3);
  887.  
  888.     // Initialize Horizontal and Vertical Alignment listboxes
  889.     CComboBox *pCombo = (CComboBox*)GetDlgItem(IDC_TABLE_CELL_ALIGN);
  890.     pCombo->AddString(szLoadString(IDS_LEFT));
  891.     pCombo->AddString(szLoadString(IDS_CENTER));
  892.     pCombo->AddString(szLoadString(IDS_RIGHT));
  893.  
  894.     pCombo = (CComboBox*)GetDlgItem(IDC_TABLE_CELL_VALIGN);
  895.     pCombo->AddString(szLoadString(IDS_TOP));
  896.     pCombo->AddString(szLoadString(IDS_CENTER));
  897.     pCombo->AddString(szLoadString(IDS_BOTTOM));
  898.     pCombo->AddString(szLoadString(IDS_BASELINE));
  899.     
  900.     // Initialize width and height Units comboboxex
  901.     pCombo = (CComboBox*)GetDlgItem(IDC_HEIGHT_PIX_OR_PERCENT);
  902.     char *pPercent = szLoadString(CASTUINT(EDT_IsInsertPointInNestedTable(m_pMWContext) ? IDS_PERCENT_PARENT_CELL : IDS_PERCENT_TABLE));
  903.     pCombo->AddString(szLoadString(IDS_PIXELS));
  904.     pCombo->AddString(pPercent);
  905.  
  906.     pCombo = (CComboBox*)GetDlgItem(IDC_WIDTH_PIX_OR_PERCENT);
  907.     pCombo->AddString(szLoadString(IDS_PIXELS));
  908.     pCombo->AddString(pPercent);
  909.  
  910.     pCombo = (CComboBox*)GetDlgItem(IDC_TABLE_SELECTION_TYPE);
  911.     pCombo->AddString(szLoadString(IDS_CELL));
  912.     pCombo->AddString(szLoadString(IDS_ROW));
  913.     pCombo->AddString(szLoadString(IDS_COLUMN));
  914.  
  915.     // Get size of parent to convert % values to pixels and vice versa
  916.     // TRUE = get size of current cell's parent, table, minus border and inter-cell space
  917.     // Use to convert pixels to "% of parent" 
  918.     EDT_GetTableParentSize(m_pMWContext, TRUE, &m_iParentWidth, &m_iParentHeight);
  919.  
  920.     // Initialize all controls based on cell data
  921.     InitPageData();
  922.  
  923.     return(TRUE);
  924. }
  925.  
  926. void CTableCellPage::InitPageData()
  927. {
  928.  
  929.     // Set currently-selected align items in comboboxes
  930.     CComboBox *pCombo = (CComboBox*)GetDlgItem(IDC_TABLE_CELL_ALIGN);
  931.     
  932.     if( m_pCellData->mask & CF_ALIGN )
  933.     {
  934.         m_iAlign = kXPToFEAlign[m_pCellData->align+1];
  935.         // Remove "Don't change" item in combo if already there
  936.         if( pCombo->GetCount() == 4 )
  937.             pCombo->DeleteString(3);
  938.     }
  939.     else
  940.     {
  941.         m_iAlign = -1;   // Empty combox = mixed styles
  942.         // Add "Dont change" item to combo if not already there
  943.         if( pCombo->GetCount() == 3 )
  944.             pCombo->AddString(ed_pDontChange);
  945.     }
  946.  
  947.     // Vertical alignment
  948.     pCombo = (CComboBox*)GetDlgItem(IDC_TABLE_CELL_VALIGN);
  949.     
  950.     if( m_pCellData->mask & CF_VALIGN )
  951.     {
  952.         m_iVAlign = kXPToFEVAlign[m_pCellData->valign+1];
  953.         // Remove "Dont change" item in combo if already there
  954.         if( pCombo->GetCount() == 5 )
  955.             pCombo->DeleteString(4);
  956.     }
  957.     else
  958.     {
  959.         m_iVAlign = -1;
  960.         // Add "Dont change" item to combo if not already there
  961.         if( pCombo->GetCount() == 4 )
  962.             pCombo->AddString(ed_pDontChange);
  963.     }
  964.  
  965.     m_iColumnSpan = CASTINT(m_pCellData->iColSpan);
  966.     m_iRowSpan = CASTINT(m_pCellData->iRowSpan);
  967.  
  968.     // Disable ColSpan and RowSpan if multiple cells selected
  969.     GetDlgItem(IDC_COLSPAN)->EnableWindow(m_pCellData->mask & CF_COLSPAN);
  970.     GetDlgItem(IDC_ROWSPAN)->EnableWindow(m_pCellData->mask & CF_ROWSPAN);
  971.  
  972.     m_iHeader = InitCheckbox(IDC_HEADER, CF_HEADER, m_pCellData->bHeader);
  973.     m_iNoWrap = InitCheckbox(IDC_WRAP, CF_NOWRAP, m_pCellData->bNoWrap);
  974.  
  975.     m_iWidth = CASTINT(m_pCellData->iWidth);
  976.     m_iWidthType = m_pCellData->bWidthPercent ? ED_PERCENT : ED_PIXELS;
  977.     m_iHeight = CASTINT(m_pCellData->iHeight);
  978.     m_iHeightType = m_pCellData->bHeightPercent ? ED_PERCENT : ED_PIXELS;
  979.  
  980.     // We don't use DDX with these so we don't get "not-integer" error messages
  981.     // Set flag to prevent changing the associated checkbox
  982.     m_bInternalChangeEditbox = TRUE;
  983.     UpdateWidthAndHeight(this, m_iWidth, m_iHeight);
  984.     m_bInternalChangeEditbox = FALSE;
  985.  
  986.     m_iUseWidth = InitCheckbox(IDC_OVERRIDE_WIDTH, CF_WIDTH, m_pCellData->bWidthDefined);
  987.     m_iUseHeight = InitCheckbox(IDC_OVERRIDE_HEIGHT, CF_HEIGHT, m_pCellData->bHeightDefined);
  988.  
  989.     BOOL bUseColor;
  990.     GetColorHelper(m_pCellData->pColorBackground, bUseColor, m_crColor);
  991.     m_iUseColor = InitCheckbox(IDC_OVERRIDE_COLOR, CF_BACK_COLOR, bUseColor);
  992.     m_csBackgroundImage = m_pCellData->pBackgroundImage;
  993.  
  994.     BOOL bHaveImage = !m_csBackgroundImage.IsEmpty();
  995.         ((CButton*)GetDlgItem(IDC_BKGRND_USE_IMAGE))->SetCheck(1);
  996.     
  997.     int iUseImage = InitCheckbox(IDC_BKGRND_USE_IMAGE, CF_BACK_IMAGE, bHaveImage);
  998.     ((CButton*)GetDlgItem(IDC_BKGRND_USE_IMAGE))->SetCheck(iUseImage);
  999.  
  1000.     if( iUseImage == 1 && m_iUseColor == 1 )
  1001.     {
  1002.          // Clear the current color checkbox ONLY 
  1003.          //   if we were sure about using image
  1004.          //   we were going to use color
  1005.          m_iUseColor = 0;
  1006.         ((CButton*)GetDlgItem(IDC_OVERRIDE_COLOR))->SetCheck(0);
  1007.     }
  1008.  
  1009.     // Disable original location checkbox if using color
  1010.     if( m_iUseColor )
  1011.     {
  1012.         GetDlgItem(IDC_NO_SAVE_IMAGE)->EnableWindow(FALSE);
  1013.     }
  1014.  
  1015.     // Flag to leave image at original location and not save with page
  1016.     m_bNoSave = m_pCellData->bBackgroundNoSave;
  1017.  
  1018.     // Get type of cell set selected and set combobox
  1019.     m_iSelectionType = m_pCellData->iSelectionType;
  1020.     // Not sure if this is needed????
  1021.     if( m_iSelectionType != ED_HIT_SEL_ROW && m_iSelectionType != ED_HIT_SEL_COL )
  1022.     {
  1023.         m_iSelectionType = ED_HIT_SEL_CELL;
  1024.     }
  1025.     pCombo = (CComboBox*)GetDlgItem(IDC_TABLE_SELECTION_TYPE);
  1026.     pCombo->SetCurSel(kXPToFESelType[m_iSelectionType]);
  1027.  
  1028.     // SetPageTitle only works in Win32
  1029.     // How do we set tab text in Win16?
  1030.     // Maybe set m_strCaption directly?
  1031.     CNetscapePropertySheet *pSheet = (CNetscapePropertySheet*)GetParent();
  1032.  
  1033.     if( m_pCellData->iSelectedCount > 1 )
  1034.     {
  1035.         switch( m_iSelectionType )
  1036.         {
  1037.             case ED_HIT_SEL_COL:
  1038.                 
  1039.                 pSheet->SetPageTitle(1, m_csSelectedCol);
  1040.                 break;
  1041.             case ED_HIT_SEL_ROW:
  1042.                 pSheet->SetPageTitle(1, m_csSelectedRow);
  1043.                 break;
  1044.             default:
  1045.                 pSheet->SetPageTitle(1, m_csSelectedCells);
  1046.                 break;
  1047.         }
  1048.     } else {
  1049.         pSheet->SetPageTitle(1, m_csSingleCell);
  1050.     }
  1051.  
  1052.     // Send rest of the data to controls
  1053.     UpdateData(FALSE);
  1054.     
  1055.     // Gray out the APPLY button
  1056.     SetModified(FALSE);
  1057.  
  1058.     // Force redrawing entire page
  1059.     Invalidate(FALSE);
  1060. }
  1061.  
  1062. int CTableCellPage::InitCheckbox(UINT nIDCheckbox, ED_CellFormat cf, BOOL bSetState)
  1063. {
  1064.     int iState;
  1065.     CButton *pButton = ((CButton*)GetDlgItem(nIDCheckbox));
  1066.  
  1067.     // Get current style but clear all relevant button-style bits
  1068.     UINT nStyle = CASTUINT(pButton->GetButtonStyle() & 0xFFFFFFF0L);
  1069.  
  1070.     if( m_pCellData->mask & cf )
  1071.     {
  1072.         // We know the style, so we can use 2-state boxes
  1073.         nStyle |= BS_AUTOCHECKBOX;
  1074.         iState = bSetState ? 1 : 0;
  1075.     } else 
  1076.     {
  1077.         // We don't know the style, so we use 3-state boxes
  1078.         //  so user can return to the "don't change" state
  1079.         nStyle |= BS_AUTO3STATE;
  1080.         // Set initial value to the indeterminate state
  1081.         iState = 2;
  1082.     }
  1083.     pButton->SetButtonStyle(nStyle);
  1084.  
  1085.     return iState;
  1086. }
  1087.  
  1088. // Called before OnOK to do validation
  1089. BOOL CTableCellPage::OnKillActive()
  1090. {
  1091.     // never visited this page or no change -- don't bother
  1092.     if(!m_bActivated ||
  1093.        !IS_APPLY_ENABLED(this))
  1094.     {
  1095.         return TRUE;
  1096.     }
  1097.     if ( !UpdateData(TRUE) ||
  1098.          !ValidateWidthAndHeight(this, &m_iWidth, &m_iHeight, m_iWidthType, m_iHeightType) )
  1099.     {
  1100.         return FALSE;
  1101.     }
  1102.  
  1103.     if ( !m_csBackgroundImage.IsEmpty() )
  1104.     {
  1105.         if ( m_bImageChanged && !m_bValidImage )
  1106.         {
  1107.             if( ((CButton*)GetDlgItem(IDC_BKGRND_USE_IMAGE))->GetCheck() == 1 &&
  1108.                 !wfe_ValidateImage( m_pMWContext, m_csBackgroundImage, FALSE ) )
  1109.             {
  1110.                 ((CButton*)GetDlgItem(IDC_BKGRND_USE_IMAGE))->SetCheck(0);
  1111.                 GetDlgItem(IDC_NO_SAVE_IMAGE)->EnableWindow(FALSE);
  1112.                 return FALSE;
  1113.             }
  1114.             // Send changed image back to editbox in case this is Apply usage
  1115.             UpdateData(FALSE);
  1116.         }
  1117.     }
  1118.  
  1119.     if( ((CButton*)GetDlgItem(IDC_BKGRND_USE_IMAGE))->GetCheck() == 1 &&
  1120.         !m_csBackgroundImage.IsEmpty() )
  1121.     {
  1122.         wfe_ValidateImage( m_pMWContext, m_csBackgroundImage );
  1123.         int iLastDot = m_csBackgroundImage.ReverseFind('.');
  1124.         CString csExt;
  1125.         if(iLastDot > 0)
  1126.             csExt= m_csBackgroundImage.Mid(iLastDot);
  1127.  
  1128.         //we must check to see if file is a bmp!
  1129.         if (0 == csExt.CompareNoCase(".bmp"))
  1130.         {
  1131.             char *t_outputfilename=wfe_ConvertImage(m_csBackgroundImage.GetBuffer(0),(void *)this,m_pMWContext);
  1132.             if (t_outputfilename)
  1133.             {
  1134.                 m_csBackgroundImage=t_outputfilename;
  1135.                 wfe_ValidateImage( m_pMWContext, m_csBackgroundImage );
  1136.                 XP_FREE(t_outputfilename);
  1137.                 UpdateData(FALSE);//we need to update m_csImage!
  1138.             }
  1139.             else 
  1140.                 return FALSE;
  1141.         }
  1142.     }
  1143.     return TRUE;
  1144. }
  1145.  
  1146. void CTableCellPage::OnOK() 
  1147. {
  1148.     // never visited this page or no change -- don't bother
  1149.     if(!m_bActivated ||
  1150.        !IS_APPLY_ENABLED(this))
  1151.     {
  1152.         return;
  1153.     }
  1154.  
  1155.     if ( !UpdateData(TRUE) ||
  1156.          !ValidateWidthAndHeight(this, &m_iWidth, &m_iHeight, m_iWidthType, m_iHeightType) )
  1157.     {
  1158.         return;
  1159.     }
  1160.  
  1161.     // Use checkbox states and set/clear mask bits and data appropriately
  1162.  
  1163.     // This checkbox is not hooked up to DDX    
  1164.     int iCheckState = ((CButton*)GetDlgItem(IDC_BKGRND_USE_IMAGE))->GetCheck();
  1165.     
  1166.     // Clear background image unless we shouldn't change it
  1167.     if( iCheckState != 2 )
  1168.         XP_FREEIF( m_pCellData->pBackgroundImage );
  1169.  
  1170.     if( iCheckState == 1 &&
  1171.         !m_csBackgroundImage.IsEmpty() )
  1172.     {
  1173.         m_pCellData->pBackgroundImage = XP_STRDUP(m_csBackgroundImage);
  1174.  
  1175.         // Save state of flag from checkbox
  1176.         m_pCellData->bBackgroundNoSave = m_bNoSave;
  1177.     }
  1178.  
  1179.     if( m_iAlign == -1 )
  1180.     {
  1181.         // Don't change this attribute
  1182.         FE_CLEAR_BIT(m_pCellData->mask, CF_ALIGN);
  1183.     } else {
  1184.         // We are sure user wants to set this
  1185.         FE_SET_BIT(m_pCellData->mask, CF_ALIGN);
  1186.     }
  1187.     m_pCellData->align = kFEToXPAlign[m_iAlign];
  1188.  
  1189.     if( m_iVAlign == -1 )
  1190.     {
  1191.         FE_CLEAR_BIT(m_pCellData->mask, CF_VALIGN);
  1192.     } else {
  1193.         FE_SET_BIT(m_pCellData->mask, CF_VALIGN);
  1194.     }
  1195.     m_pCellData->valign = kFEToXPVAlign[m_iVAlign];
  1196.  
  1197.     // These can't change if disabled, so it doesn't 
  1198.     //  hurt to get values no matter what
  1199.     m_pCellData->iColSpan = m_iColumnSpan;
  1200.     m_pCellData->iRowSpan = m_iRowSpan;
  1201.  
  1202.     if( m_iUseColor == 2 )
  1203.     {
  1204.         FE_CLEAR_BIT(m_pCellData->mask, CF_BACK_COLOR);
  1205.     } else {
  1206.         FE_SET_BIT(m_pCellData->mask, CF_BACK_COLOR);
  1207.         SetColorHelper(m_iUseColor == 1, m_crColor, &m_pCellData->pColorBackground);
  1208.     }
  1209.  
  1210.     if( m_iHeader == 2 )
  1211.     {
  1212.         FE_CLEAR_BIT(m_pCellData->mask, CF_HEADER);
  1213.     } else {
  1214.         FE_SET_BIT(m_pCellData->mask, CF_HEADER);
  1215.         m_pCellData->bHeader = m_iHeader > 0;
  1216.     }
  1217.  
  1218.     if( m_iNoWrap == 2 )
  1219.     {
  1220.         FE_CLEAR_BIT(m_pCellData->mask, CF_NOWRAP);
  1221.     } else {
  1222.         FE_SET_BIT(m_pCellData->mask, CF_NOWRAP);
  1223.         m_pCellData->bNoWrap = m_iNoWrap > 0;
  1224.     }
  1225.  
  1226.     if( m_iUseHeight == 2 )
  1227.     {
  1228.         FE_CLEAR_BIT(m_pCellData->mask, CF_HEIGHT);
  1229.     } else {
  1230.         FE_SET_BIT(m_pCellData->mask, CF_HEIGHT);
  1231.         m_pCellData->iHeight = m_iHeight;
  1232.         m_pCellData->bHeightPercent = (m_iHeightType == ED_PERCENT);
  1233.     }
  1234.     m_pCellData->bHeightDefined = (m_iUseHeight == 1);
  1235.     
  1236.     if( m_iUseWidth == 2 )
  1237.     {
  1238.         FE_CLEAR_BIT(m_pCellData->mask, CF_WIDTH);
  1239.     } else {
  1240.         FE_SET_BIT(m_pCellData->mask, CF_WIDTH);
  1241.         m_pCellData->iWidth = m_iWidth;
  1242.         m_pCellData->bWidthPercent = (m_iWidthType == ED_PERCENT);
  1243.     }
  1244.     m_pCellData->bWidthDefined = (m_iUseWidth == 1);
  1245.     
  1246.     EDT_SetTableCellData(m_pMWContext, m_pCellData);
  1247.  
  1248.     // TODO: WE MAY NOT NEED THIS AFTER NEW LAYOUT WORK
  1249.     // We must call this here else special selection is lost
  1250.     EDT_StartSpecialCellSelection(m_pMWContext, m_pCellData);
  1251.  
  1252.     OkToClose(); // CancelToClose() doesn't work!
  1253.     CPropertyPage::OnOK();
  1254.     
  1255.     // These may be different as a result of Relayout during EDT_SetTableData()
  1256.     //  (Backend fixes up size data to reflect layout algorithms)
  1257.     m_iWidth = m_pCellData->iWidth;
  1258.     m_iHeight = m_pCellData->iHeight;
  1259.  
  1260.     // Get possibly new size of parent because of Relayout
  1261.     EDT_GetTableParentSize(m_pMWContext, TRUE, &m_iParentWidth, &m_iParentHeight);
  1262.  
  1263.     // We don't use DDX with these so we don't get "not-integer" error messages
  1264.     // Set flag to prevent changing the associated checkbox
  1265.     m_bInternalChangeEditbox = TRUE;
  1266.     UpdateWidthAndHeight(this, m_iWidth, m_iHeight);
  1267.     m_bInternalChangeEditbox = FALSE;
  1268. }
  1269.  
  1270. void CTableCellPage::OnChangeSelectionType()
  1271. {
  1272.     CComboBox *pCombo = (CComboBox*)GetDlgItem(IDC_TABLE_SELECTION_TYPE);
  1273.  
  1274.     // Get selection type from combobox    
  1275.     m_iSelectionType = kFEToXPSelType[pCombo->GetCurSel()];
  1276.     
  1277.     // Change selection, but don't move focus cell
  1278.     ChangeSelection(ED_MOVE_NONE);
  1279. }
  1280.  
  1281. void CTableCellPage::ChangeSelection(ED_MoveSelType iMoveType)
  1282. {
  1283.     if( iMoveType != ED_MOVE_NONE && IS_APPLY_ENABLED(this) &&
  1284.         IDYES == MessageBox(szLoadString(IDS_APPLY_CELL_MSG), szLoadString(IDS_CHANGE_SEL_CAPTION),
  1285.                             MB_YESNO | MB_ICONQUESTION) )
  1286.     {
  1287.         // Save current data
  1288.         if( OnKillActive() )
  1289.         {
  1290.             OnOK();
  1291.         } else {
  1292.             return;
  1293.         }
  1294.     }
  1295.  
  1296.     EDT_ChangeTableSelection(m_pMWContext, m_iSelectionType, iMoveType, m_pCellData);
  1297.     InitPageData();
  1298. }
  1299.  
  1300. void CTableCellPage::OnPrevious()
  1301. {
  1302.     ChangeSelection(ED_MOVE_PREV);
  1303. }
  1304.  
  1305. void CTableCellPage::OnNext()
  1306. {
  1307.     ChangeSelection(ED_MOVE_NEXT);
  1308. }
  1309.  
  1310. void CTableCellPage::OnHelp() 
  1311. {
  1312.     NetHelp(HELP_TABLE_PROPS_CELL);
  1313. }
  1314.  
  1315. void CTableCellPage::OnExtraHTML()
  1316. {
  1317.     CExtraHTMLDlg dlg(this, &m_pCellData->pExtra, IDS_TD_TAG);
  1318.     if( IDOK == dlg.DoModal() )
  1319.     {
  1320.         SetModified(TRUE);
  1321.     }
  1322. }
  1323.  
  1324. void CTableCellPage::OnChangeWidth()
  1325. {
  1326.     if( !m_bInternalChangeEditbox )
  1327.     {
  1328.         SetModified(TRUE);
  1329.         m_iUseWidth = TRUE;
  1330.         ((CButton*)GetDlgItem(IDC_OVERRIDE_WIDTH))->SetCheck(1);
  1331.     }
  1332. }
  1333.  
  1334. void CTableCellPage::OnChangeWidthType()
  1335. {
  1336.     // See if type has changed and we need to convert
  1337.     //   to opposite type (pixels <-> percent of parent)
  1338.     int iWidthType = ((CComboBox*)GetDlgItem(IDC_WIDTH_PIX_OR_PERCENT))->GetCurSel();
  1339.     if( iWidthType != m_iWidthType )
  1340.     {
  1341.         // Get current data from edit box before converting
  1342.         // Note that validation uses NEW width type 
  1343.         if( ValidateWidthAndHeight(this, &m_iWidth, &m_iHeight, iWidthType, m_iHeightType) )
  1344.         {
  1345.             if( iWidthType ) 
  1346.             {
  1347.                 // New type = %
  1348.                 // Convert previous value from pixels to %
  1349.                 m_iWidth = (m_iWidth * 100) / m_iParentWidth;
  1350.             } else {
  1351.                 // New type = pixels
  1352.                 // Convert previous from % to pixels
  1353.                 m_iWidth = (m_iWidth * m_iParentWidth ) / 100;
  1354.             }
  1355.  
  1356.             UpdateWidthAndHeight(this, m_iWidth, m_iHeight);
  1357.             SetModified(TRUE);
  1358.         }
  1359.         m_iWidthType = iWidthType;
  1360.     }
  1361. }
  1362.  
  1363. void CTableCellPage::OnChangeHeight()
  1364. {
  1365.     if( !m_bInternalChangeEditbox )
  1366.     {
  1367.         SetModified(TRUE);
  1368.         m_iUseHeight = 1;
  1369.         ((CButton*)GetDlgItem(IDC_OVERRIDE_HEIGHT))->SetCheck(1);
  1370.     }
  1371. }
  1372.  
  1373. void CTableCellPage::OnChangeHeightType()
  1374. {
  1375.     // See if type has changed and we need to convert
  1376.     //   to opposite type (pixels <-> percent of parent)
  1377.     int iHeightType = ((CComboBox*)GetDlgItem(IDC_HEIGHT_PIX_OR_PERCENT))->GetCurSel();
  1378.     if( iHeightType != m_iHeightType )
  1379.     {
  1380.         // Get current data from edit box before converting
  1381.         // Note that validation uses NEW height type 
  1382.         if( ValidateWidthAndHeight(this, &m_iWidth, &m_iHeight, m_iWidthType, iHeightType) )
  1383.         {
  1384.             if( iHeightType )
  1385.                 // Convert previous from % to pixels
  1386.                 m_iHeight = (m_iHeight * m_iParentHeight ) / 100;
  1387.             else 
  1388.                 // Convert previous value from pixels to %
  1389.                 m_iHeight = (m_iHeight * 100) / m_iParentHeight;
  1390.  
  1391.             UpdateWidthAndHeight(this, m_iWidth, m_iHeight);
  1392.             SetModified(TRUE);
  1393.         }
  1394.         m_iHeightType = iHeightType;
  1395.     }
  1396. }
  1397.  
  1398. void CTableCellPage::OnOverrideColor() 
  1399. {
  1400.     m_iUseColor = ((CButton*)GetDlgItem(IDC_OVERRIDE_COLOR))->GetCheck();
  1401.     SetModified(TRUE);
  1402. }
  1403.  
  1404. void CTableCellPage::OnChooseColor() 
  1405. {
  1406.     // Get the combobox location so we popup new dialog just under it
  1407.     RECT rect;
  1408.     GetDlgItem(IDC_CHOOSE_COLOR)->GetWindowRect(&rect);
  1409.  
  1410.     CColorPicker dlg(this, m_pMWContext, m_crColor, BACKGROUND_COLORREF, 0, &rect);
  1411.  
  1412.     COLORREF crNew = dlg.GetColor();
  1413.     if( crNew != CANCEL_COLORREF )
  1414.     {
  1415.         m_crColor = crNew;
  1416.         if(m_crColor == DEFAULT_COLORREF)
  1417.         {
  1418.             m_crColor = prefInfo.m_rgbBackgroundColor;
  1419.         }
  1420.         m_iUseColor = 1;
  1421.         ((CButton*)GetDlgItem(IDC_OVERRIDE_COLOR))->SetCheck(m_iUseColor);
  1422.         m_ColorButton.Update();
  1423.         SetModified(TRUE);
  1424.     }
  1425. }
  1426.  
  1427. void CTableCellPage::OnUseBkgrndImage() 
  1428. {
  1429.     int iUseImageBackground = ((CButton*)GetDlgItem(IDC_BKGRND_USE_IMAGE))->GetCheck();;
  1430.     SetModified(TRUE);
  1431.     if( iUseImageBackground )
  1432.     {
  1433.         // User decided to use the image, so do trigger validation
  1434.         if( !m_csBackgroundImage.IsEmpty() && 
  1435.             wfe_ValidateImage( m_pMWContext, m_csBackgroundImage, FALSE /*TRUE*/ ) )
  1436.         {
  1437.             ((CButton*)GetDlgItem(IDC_BKGRND_USE_IMAGE))->SetCheck(1);
  1438.         } else {
  1439.             GetDlgItem(IDC_BKGRND_IMAGE)->SetFocus();
  1440.         }
  1441.         m_bValidImage = TRUE;
  1442.     }
  1443.     GetDlgItem(IDC_NO_SAVE_IMAGE)->EnableWindow(iUseImageBackground);
  1444. }
  1445.  
  1446. void CTableCellPage::OnChooseBkgrndImage() 
  1447. {
  1448.     UpdateData(TRUE);
  1449.     char * szFilename = wfe_GetExistingImageFileName(this->m_hWnd, 
  1450.                                          szLoadString(IDS_SELECT_IMAGE), TRUE);
  1451.     if ( szFilename == NULL )
  1452.         return;
  1453.  
  1454.     m_csBackgroundImage = szFilename;
  1455.     if( wfe_ValidateImage( m_pMWContext, m_csBackgroundImage, FALSE /*TRUE*/ ) )
  1456.     {
  1457.         ((CButton*)GetDlgItem(IDC_BKGRND_USE_IMAGE))->SetCheck(1);
  1458.         GetDlgItem(IDC_NO_SAVE_IMAGE)->EnableWindow(TRUE);
  1459.     } else {
  1460.         ((CButton*)GetDlgItem(IDC_BKGRND_USE_IMAGE))->SetCheck(0);
  1461.         GetDlgItem(IDC_NO_SAVE_IMAGE)->EnableWindow(FALSE);
  1462.     }
  1463.  
  1464.     // Send new name to editbox
  1465.     UpdateData(FALSE);
  1466.  
  1467.     XP_FREE( szFilename );
  1468.     m_bValidImage = TRUE;
  1469.     m_bImageChanged = FALSE;
  1470.     SetModified(TRUE);
  1471. }
  1472.  
  1473. void CTableCellPage::OnChangeBkgrndImage() 
  1474. {
  1475.     // Set flags to trigger validation
  1476.     m_bValidImage = FALSE;
  1477.     m_bImageChanged = TRUE;
  1478.     
  1479.     UpdateData(TRUE);
  1480.     CString csTemp = m_csBackgroundImage;
  1481.     csTemp.TrimLeft();
  1482.     csTemp.TrimRight();
  1483.  
  1484.     // Set checkbox if there are any characters, clear if empty
  1485.     ((CButton*)GetDlgItem(IDC_BKGRND_USE_IMAGE))->SetCheck(!csTemp.IsEmpty());
  1486.     if(!csTemp.IsEmpty())
  1487.     {
  1488.         GetDlgItem(IDC_NO_SAVE_IMAGE)->EnableWindow(TRUE);
  1489.     }
  1490.     SetModified(TRUE);
  1491. }
  1492.  
  1493. void CTableCellPage::OnChangeHAlign()
  1494. {
  1495.     SetModified(TRUE);
  1496.     // When user selects last item ("Don't change"),
  1497.     //  change selected item to empty combobox
  1498.     CComboBox *pCombo = (CComboBox*)GetDlgItem(IDC_TABLE_CELL_ALIGN);
  1499.     m_iAlign = pCombo->GetCurSel();
  1500.     if( m_iAlign == 3 )
  1501.     {
  1502.         m_iAlign = -1;
  1503.         pCombo->SetCurSel(-1);
  1504.     }
  1505. }
  1506.  
  1507. void CTableCellPage::OnChangeVAlign()
  1508. {
  1509.     SetModified(TRUE);
  1510.     CComboBox *pCombo = (CComboBox*)GetDlgItem(IDC_TABLE_CELL_VALIGN);
  1511.     m_iVAlign = pCombo->GetCurSel();
  1512.     if( m_iVAlign == 4 )
  1513.     {
  1514.         m_iVAlign = -1;
  1515.         pCombo->SetCurSel(-1);
  1516.     }
  1517. }
  1518.  
  1519. void CTableCellPage::OnInsert()
  1520. {
  1521.     //TODO: ADD INSERT DIALOG
  1522. }
  1523.  
  1524.  
  1525. void CTableCellPage::OnDelete()
  1526. {
  1527.     //TODO: ADD DELETE DIALOG
  1528. }
  1529.  
  1530. // Shared message handler for controls that
  1531. //  only need to change Apply state
  1532. void CTableCellPage::EnableApplyButton()
  1533. {
  1534.     SetModified(TRUE);
  1535. }
  1536.  
  1537. /////////////////////////////////////////////////////////////////
  1538.