gecko-dev/cmd/winfe/edtable.cpp

1641 lines
53 KiB
C++
Executable File

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
// edtable.cpp : implementation file
//
#include "stdafx.h"
#include "property.h"
#include "edtable.h"
#include "styles.h"
#include "edt.h"
#include "edprops.h"
#include "nethelp.h"
#include "xp_help.h"
#include "prefinfo.h"
#include "prefapi.h"
// the dialog box & string resources are in edtrcdll DLL
#include "edtrcdll\src\resource.h"
// Global string in EDFRAME.CPP: "Don't change"
extern char * ed_pDontChange;
// Convert the front-end valign (0..2) to the back end alignment codes.
// FE Vertical: Top, Center, Bottom, // [NO MORE "Baseline"]
// FE Horizontal: Left, center, right
static const ED_Alignment kFEToXPVAlign[3] = {ED_ALIGN_ABSTOP, ED_ALIGN_ABSCENTER, ED_ALIGN_ABSBOTTOM};
static const ED_Alignment kFEToXPAlign[3] = {ED_ALIGN_LEFT, ED_ALIGN_ABSCENTER, ED_ALIGN_RIGHT };
// Base -1 (default = -1)
// default center left right top bottom baseline abscenter absbottom abstop
static const int kXPToFEAlign[10] = {0, 1, 0, 2, -1, -1, -1, 1, -1, -1}; // Default is shown as LEFT in listbox
static const int kXPToFEVAlign[10] = {1, -1, -1, -1, 0, 2, 2, 1, 2, 0}; // Default is shown as CENTER in listbox
static const ED_HitType kFEToXPSelType[3] = {ED_HIT_SEL_CELL, ED_HIT_SEL_ROW, ED_HIT_SEL_COL};
static const int kXPToFESelType[10] = {-1, -1, 2, 1, 0, 0, -1, -1, -1, -1};
void SetColorHelper(BOOL bOverride, COLORREF crColor, LO_Color** ppLoColor)
{
if ( !bOverride || crColor == DEFAULT_COLORREF) {
if ( *ppLoColor ) {
XP_FREE(*ppLoColor);
}
*ppLoColor = NULL; /* null in the default case */
}
else {
// Allocates the pColorBackground pointer.
WFE_SetLO_ColorPtr( crColor, ppLoColor );
}
}
void GetColorHelper(LO_Color* pLoColor, BOOL& bOverride, COLORREF& crColor)
{
bOverride = pLoColor != NULL;
if( bOverride ){
crColor = WFE_LO2COLORREF( pLoColor, LO_COLOR_BG );
} else {
crColor = DEFAULT_COLORREF;
}
}
#define ED_PIXELS 0
#define ED_PERCENT 1
void UpdateWidthAndHeight(CDialog* pPage, int iWidth, int iHeight)
{
char szBuf[16];
wsprintf(szBuf, "%d", iWidth);
pPage->GetDlgItem(IDC_WIDTH)->SetWindowText(szBuf);
wsprintf(szBuf, "%d", iHeight);
pPage->GetDlgItem(IDC_HEIGHT)->SetWindowText(szBuf);
}
BOOL ValidateWidthAndHeight(CDialog* pPage,
int* iWidth, int* iHeight,
int iWidthType, int iHeightType)
{
char szMessage[256];
CEdit* pWidthControl = (CEdit*)(pPage->GetDlgItem(IDC_WIDTH));
CEdit* pHeightControl = (CEdit*)(pPage->GetDlgItem(IDC_HEIGHT));
ASSERT (pWidthControl);
ASSERT (pHeightControl);
char szWidth[16] = "";
char szHeight[16] = "";
char *szEndWidth;
char *szEndHeight;
pWidthControl->GetWindowText(szWidth, 15);
pHeightControl->GetWindowText(szHeight, 15);
int width = (int)strtol( szWidth, &szEndWidth, 10 );
int height = (int)strtol( szHeight, &szEndHeight, 10 );
int iMaxWidth = (iWidthType == ED_PERCENT) ? 100 : MAX_TABLE_PIXELS;
int iMaxHeight = (iHeightType == ED_PERCENT) ? 100 : MAX_TABLE_PIXELS;;
// If we have a checkbox to use width/height, validate range only if it is checked
// Bad conversion if end pointer isn't at terminal null;
BOOL bHaveWidthCheck = pPage->GetDlgItem(IDC_OVERRIDE_WIDTH) &&
((CButton*)pPage->GetDlgItem(IDC_OVERRIDE_WIDTH))->GetCheck();
BOOL bHaveHeightCheck = pPage->GetDlgItem(IDC_OVERRIDE_HEIGHT) &&
((CButton*)pPage->GetDlgItem(IDC_OVERRIDE_HEIGHT))->GetCheck();
// Minimum value is always 1
BOOL bBadWidth = bHaveWidthCheck &&
( (width < 1 || width > iMaxWidth) || *szEndWidth != '\0');
BOOL bBadHeight = bHaveHeightCheck &&
( (height< 1 || height > iMaxHeight) || *szEndHeight != '\0');
if( bBadWidth || bBadHeight ){
// Note: We only show 1 error at a time, so allways check Width error first
// Construct a string showing correct range
wsprintf( szMessage, szLoadString(IDS_INTEGER_RANGE_ERROR), 1,
bBadWidth ? iMaxWidth : iMaxHeight );
// Notify user with similar message to the DDV_ validation system
pPage->MessageBox(szMessage, szLoadString(AFX_IDS_APP_TITLE), MB_ICONEXCLAMATION | MB_OK);
// Put focus in the offending control
// And select all text, just like DDV functions
if( bBadWidth ){
pWidthControl->SetFocus();
pWidthControl->SetSel(0, -1, TRUE);
} else {
pHeightControl->SetFocus();
pHeightControl->SetSel(0, -1, TRUE);
}
return FALSE;
}
// Save values if they are good
if( width > 0 ){
*iWidth = width;
}
if( height > 0 ){
*iHeight = height;
}
return TRUE;
}
void SetTableCaption(MWContext * pMWContext, int iCaptionIndex)
{
// Try to get existing caption data
EDT_TableCaptionData* pTableCaptionData = EDT_GetTableCaptionData(pMWContext);
// NOTE: We shouldn't set insert point to the caption when it is inserted!
// so don't use that as test for existing caption
BOOL bAlreadyHaveCaption = pTableCaptionData != NULL;
if ( iCaptionIndex > 0 ) {
if ( !bAlreadyHaveCaption ) {
// Create new caption
pTableCaptionData = EDT_NewTableCaptionData();
}
if ( pTableCaptionData ) {
pTableCaptionData->align = (iCaptionIndex == 1 ? ED_ALIGN_ABSTOP : ED_ALIGN_ABSBOTTOM);
if( bAlreadyHaveCaption ){
// Change existing caption data
EDT_SetTableCaptionData(pMWContext, pTableCaptionData);
} else {
// Insert a new caption
EDT_InsertTableCaption(pMWContext, pTableCaptionData);
}
EDT_FreeTableCaptionData(pTableCaptionData);
}
} else if ( bAlreadyHaveCaption ) {
// We have a caption but user changed to "none" so remove it
EDT_DeleteTableCaption(pMWContext);
}
}
int GetTableAlign(EDT_TableData * pTableData)
{
int iAlign = 0; // Default = Left align
if( pTableData ){
switch ( pTableData->align){
case ED_ALIGN_CENTER:
case ED_ALIGN_ABSCENTER:
iAlign = 1;
break;
case ED_ALIGN_RIGHT:
iAlign = 2;
break;
}
}
return iAlign;
}
void SetTableAlign(EDT_TableData * pTableData, int iAlign)
{
if( pTableData ){
switch ( iAlign ){
case 1:
pTableData->align = ED_ALIGN_ABSCENTER;
break;
case 2:
pTableData->align = ED_ALIGN_RIGHT;
break;
default: // 0 or -1
pTableData->align = ED_ALIGN_LEFT;
}
}
}
//////////////////////////////////////////////////////
//
// Property pages for Table and Cell Table properties
//
/////////////////////////////////////////////////////////////////////
CTablePage::CTablePage(CWnd *pParent, MWContext * pMWContext,
CEditorResourceSwitcher * pResourceSwitcher,
EDT_TableData * pTableData)
: CNetscapePropertyPage(CTablePage::IDD),
m_bActivated(0),
m_bModified(0),
m_pMWContext(pMWContext),
m_pResourceSwitcher(pResourceSwitcher),
m_pTableData(0 /*pTableData*/),
m_bCustomColor(0),
m_crColor(DEFAULT_COLORREF),
m_iParentWidth(0),
m_iParentHeight(0),
m_bInternalChangeEditbox(0),
m_iStartColumns(0),
m_iStartRows(0)
{
ASSERT(pMWContext);
//{{AFX_DATA_INIT(CPage)
m_iRows = 0;
m_iColumns = 0;
m_iAlign = -1;
m_iCaption = 0;
m_iBorderWidth = 0;
m_iCellPadding = 0;
m_iCellSpacing = 0;
m_bColumnHeader = FALSE;
m_bUseColor = FALSE;
m_bUseHeight = FALSE;
m_bUseWidth = FALSE;
m_iHeight = 1;
m_iHeightType = 0;
m_iWidthType = 0;
m_bRowHeader = FALSE;
m_iWidth = 1;
m_csBackgroundImage = _T("");
m_bNoSave = 0;
m_bBorderWidthDefined = FALSE;
//}}AFX_DATA_INIT
#ifdef XP_WIN32
// Set the hInstance so we get template from editor's resource DLL
m_psp.hInstance = AfxGetResourceHandle();
#endif
}
CTablePage::~CTablePage()
{
if( m_pTableData )
EDT_FreeTableData(m_pTableData);
}
void CTablePage::DoDataExchange(CDataExchange* pDX)
{
CPropertyPage::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CTablePage)
DDX_Text(pDX, IDC_ROWS, m_iRows);
DDX_Text(pDX, IDC_COLUMNS, m_iColumns);
DDX_CBIndex(pDX, IDC_TABLE_ALIGN, m_iAlign);
DDX_CBIndex(pDX, IDC_TABLE_CAPTION, m_iCaption);
DDX_Text(pDX, IDC_BORDER, m_iBorderWidth);
DDV_MinMaxInt(pDX, m_iBorderWidth, 0, MAX_TABLE_PIXELS);
DDX_Text(pDX, IDC_CELL_PADDING, m_iCellPadding);
DDV_MinMaxInt(pDX, m_iCellPadding, 0, MAX_TABLE_PIXELS);
DDX_Text(pDX, IDC_CELL_SPACING, m_iCellSpacing);
DDV_MinMaxInt(pDX, m_iCellSpacing, 0, MAX_TABLE_PIXELS);
DDX_Check(pDX, IDC_OVERRIDE_COLOR, m_bUseColor);
DDX_Check(pDX, IDC_OVERRIDE_HEIGHT, m_bUseHeight);
DDX_Check(pDX, IDC_OVERRIDE_WIDTH, m_bUseWidth);
DDX_CBIndex(pDX, IDC_WIDTH_PIX_OR_PERCENT, m_iWidthType);
DDX_CBIndex(pDX, IDC_HEIGHT_PIX_OR_PERCENT, m_iHeightType);
DDX_Text(pDX, IDC_BKGRND_IMAGE, m_csBackgroundImage);
DDX_Check(pDX, IDC_NO_SAVE_IMAGE, m_bNoSave);
DDX_Check(pDX, IDC_USE_BORDER, m_bBorderWidthDefined);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CTablePage, CNetscapePropertyPage)
//{{AFX_MSG_MAP(CTablePage)
ON_EN_CHANGE(IDC_ROWS, EnableApplyButton)
ON_EN_CHANGE(IDC_COLUMNS, EnableApplyButton)
ON_EN_CHANGE(IDC_ROWS, EnableApplyButton)
ON_EN_CHANGE(IDC_COLUMNS, EnableApplyButton)
ON_EN_CHANGE(IDC_CELL_SPACING, EnableApplyButton)
ON_EN_CHANGE(IDC_CELL_PADDING, EnableApplyButton)
ON_CBN_SELCHANGE(IDC_TABLE_ALIGN, EnableApplyButton)
ON_CBN_SELCHANGE(IDC_TABLE_CAPTION, EnableApplyButton)
ON_BN_CLICKED(IDC_OVERRIDE_WIDTH, EnableApplyButton)
ON_BN_CLICKED(IDC_USE_BORDER, EnableApplyButton)
ON_EN_CHANGE(IDC_BORDER, OnChangeBorder)
ON_EN_CHANGE(IDC_WIDTH, OnChangeWidth)
ON_CBN_SELCHANGE(IDC_WIDTH_PIX_OR_PERCENT, OnChangeWidthType)
ON_BN_CLICKED(IDC_OVERRIDE_HEIGHT, EnableApplyButton)
ON_EN_CHANGE(IDC_HEIGHT, OnChangeHeight)
ON_CBN_SELCHANGE(IDC_HEIGHT_PIX_OR_PERCENT, OnChangeHeightType)
ON_BN_CLICKED(IDC_OVERRIDE_COLOR, OnOverrideColor)
ON_BN_CLICKED(IDC_CHOOSE_COLOR, OnChooseColor)
ON_WM_PAINT()
ON_BN_CLICKED(IDC_EXTRA_HTML, OnExtraHTML)
ON_BN_CLICKED(IDC_USE_COLS, EnableApplyButton)
ON_BN_CLICKED(IDC_BKGRND_USE_IMAGE, OnUseBkgrndImage)
ON_EN_CHANGE(IDC_BKGRND_IMAGE, OnChangeBkgrndImage)
ON_BN_CLICKED(IDC_CHOOSE_BACKGROUND, OnChooseBkgrndImage)
ON_BN_CLICKED(IDC_NO_SAVE_IMAGE, OnNoSave)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
BOOL CTablePage::OnSetActive()
{
if(m_pResourceSwitcher && !m_bActivated)
{
// We must be sure we have switched
// the first time here - before dialog creation
m_pResourceSwitcher->switchResources();
// This is usually supplied, but lets be sure
if( !m_pTableData )
m_pTableData = EDT_GetTableData(m_pMWContext);
if( !m_pTableData )
return FALSE;
// Save these as the bottom limit when changing table size
m_iStartColumns = m_pTableData->iColumns;
m_iStartRows = m_pTableData->iRows;
}
if(!CPropertyPage::OnSetActive())
return(FALSE);
if(m_bActivated)
{
// We are activating the pane after switching to cell tab and back again
// Refresh table data to get possibly-changed width and/or height
EDT_FreeTableData(m_pTableData);
m_pTableData = EDT_GetTableData(m_pMWContext);
m_iWidth = CASTINT(m_pTableData->iWidth);
m_iHeight = CASTINT(m_pTableData->iHeight);
m_iWidthType = m_pTableData->bWidthPercent ? ED_PERCENT : ED_PIXELS;
m_iHeightType = m_pTableData->bHeightPercent ? ED_PERCENT : ED_PIXELS;
m_bUseWidth = m_pTableData->bWidthDefined;
m_bUseHeight = m_pTableData->bHeightDefined;
// We don't use DDX with these so we don't get "not-integer" error messages
// Set flag to prevent changing the associated checkbox
m_bInternalChangeEditbox = TRUE;
UpdateWidthAndHeight(this, m_iWidth, m_iHeight);
m_bInternalChangeEditbox = FALSE;
UpdateData(FALSE);
return(TRUE);
}
m_bActivated = TRUE;
// Switch back to EXE's resources
if( m_pResourceSwitcher )
m_pResourceSwitcher->Reset();
if( !m_ColorButton.Subclass(this, IDC_CHOOSE_COLOR, &m_crColor) )
return FALSE;
((CEdit*)GetDlgItem(IDC_COLUMNS))->LimitText(3);
((CEdit*)GetDlgItem(IDC_ROWS))->LimitText(3);
((CEdit*)GetDlgItem(IDC_BORDER))->LimitText(5);
((CEdit*)GetDlgItem(IDC_CELL_PADDING))->LimitText(5);
((CEdit*)GetDlgItem(IDC_CELL_SPACING))->LimitText(5);
((CEdit*)GetDlgItem(IDC_HEIGHT))->LimitText(5);
((CEdit*)GetDlgItem(IDC_WIDTH))->LimitText(5);
m_iRows = m_pTableData->iRows;
m_iColumns = m_pTableData->iColumns;
m_bBorderWidthDefined = m_pTableData->bBorderWidthDefined;
m_iBorderWidth = CASTINT(m_pTableData->iBorderWidth);
m_iCellSpacing = CASTINT(m_pTableData->iCellSpacing);
m_iCellPadding = CASTINT(m_pTableData->iCellPadding);
m_iAlign = GetTableAlign(m_pTableData);
m_iWidth = CASTINT(m_pTableData->iWidth);
m_iHeight = CASTINT(m_pTableData->iHeight);
m_iWidthType = m_pTableData->bWidthPercent ? ED_PERCENT : ED_PIXELS;
m_iHeightType = m_pTableData->bHeightPercent ? ED_PERCENT : ED_PIXELS;
m_bUseWidth = m_pTableData->bWidthDefined;
m_bUseHeight = m_pTableData->bHeightDefined;
GetColorHelper(m_pTableData->pColorBackground, m_bUseColor, m_crColor);
// Fill comboboxes
CComboBox *pCombo = (CComboBox*)GetDlgItem(IDC_TABLE_ALIGN);
pCombo->AddString(szLoadString(IDS_LEFT));
pCombo->AddString(szLoadString(IDS_CENTER));
pCombo->AddString(szLoadString(IDS_RIGHT));
pCombo = (CComboBox*)GetDlgItem(IDC_TABLE_CAPTION);
pCombo->AddString(szLoadString(IDS_CAPTION_NONE));
pCombo->AddString(szLoadString(IDS_CAPTION_ABOVE));
pCombo->AddString(szLoadString(IDS_CAPTION_BELOW));
EDT_TableCaptionData* pTableCaptionData = EDT_GetTableCaptionData(m_pMWContext);
if ( pTableCaptionData )
{
m_iCaption = pTableCaptionData->align == ED_ALIGN_ABSTOP ? 1 : 2;
EDT_FreeTableCaptionData(pTableCaptionData);
}
// Initialize string: use "% of window" if not in table,
// or "% of parent cell" if we're in a cell
pCombo = (CComboBox*)GetDlgItem(IDC_HEIGHT_PIX_OR_PERCENT);
char *pPercent = szLoadString(CASTUINT(EDT_IsInsertPointInNestedTable(m_pMWContext) ? IDS_PERCENT_PARENT_CELL : IDS_PERCENT_WINDOW));
pCombo->AddString(szLoadString(IDS_PIXELS));
pCombo->AddString(pPercent);
pCombo = (CComboBox*)GetDlgItem(IDC_WIDTH_PIX_OR_PERCENT);
pCombo->AddString(szLoadString(IDS_PIXELS));
pCombo->AddString(pPercent);
// Get background image and set checkbox
m_csBackgroundImage = m_pTableData->pBackgroundImage;
if ( !m_csBackgroundImage.IsEmpty() )
{
((CButton*)GetDlgItem(IDC_BKGRND_USE_IMAGE))->SetCheck(1);
m_bUseColor = FALSE;
((CButton*)GetDlgItem(IDC_OVERRIDE_COLOR))->SetCheck(0);
}
// Disable NoSaveImage checkbox if using color
if( m_bUseColor )
GetDlgItem(IDC_NO_SAVE_IMAGE)->EnableWindow(FALSE);
// Flag to leave image at original location and not save with page
m_bNoSave = m_pTableData->bBackgroundNoSave;
// Get size of parent to convert % values to pixels and vice versa
// FALSE = get current table's "parent" data (current view or cell if nested table)
// Use to convert pixels to "% of parent"
EDT_GetTableParentSize(m_pMWContext, FALSE, &m_iParentWidth, &m_iParentHeight);
// We don't use DDX with these so we don't get "not-integer" error messages
// Set flag to prevent changing the associated checkbox
m_bInternalChangeEditbox = TRUE;
UpdateWidthAndHeight(this, m_iWidth, m_iHeight);
m_bInternalChangeEditbox = FALSE;
// Send data to controls
UpdateData(FALSE);
// Clear data-modified flag
SetModified(FALSE);
return(TRUE);
}
BOOL CTablePage::OnKillActive()
{
// never visited this page or no change -- don't bother
if(!m_bActivated || !m_bModified )
return TRUE;
if ( !UpdateData(TRUE) ||
!ValidateWidthAndHeight(this, &m_iWidth, &m_iHeight, m_iWidthType, m_iHeightType) )
{
return FALSE;
}
char szMessage[256];
CEdit *pEditbox;
UINT nID = 0;
// Don't let the user enter fewer rows or columns than already exist
if( m_iColumns < m_iStartColumns )
{
// Construct a string showing correct range
wsprintf( szMessage, szLoadString(IDS_INTEGER_RANGE_ERROR), m_iStartColumns, MAX_TABLE_COLUMNS);
nID = IDC_COLUMNS;
// Fix value - put inside allowable range
m_iColumns = min(MAX_TABLE_COLUMNS, max(m_iStartColumns, m_iColumns));
}
if( m_iRows < m_iStartRows )
{
wsprintf( szMessage, szLoadString(IDS_INTEGER_RANGE_ERROR), m_iStartRows, MAX_TABLE_ROWS);
nID = IDC_ROWS;
m_iRows = min(MAX_TABLE_COLUMNS, max(m_iStartRows, m_iRows));
}
if( nID )
{
// Notify user with similar message to the DDV_ validation system
MessageBox(szMessage, szLoadString(AFX_IDS_APP_TITLE), MB_ICONEXCLAMATION | MB_OK);
// Put focus in the offending control
// And select all text, just like DDV functions
pEditbox = (CEdit*)GetDlgItem(nID);
pEditbox->SetFocus();
pEditbox->SetSel(0, -1, TRUE);
// Write fixed value back to editbox
UpdateData(FALSE);
return FALSE;
}
if ( !m_csBackgroundImage.IsEmpty() )
{
if ( m_bImageChanged && !m_bValidImage )
{
if( ((CButton*)GetDlgItem(IDC_BKGRND_USE_IMAGE))->GetCheck() &&
!wfe_ValidateImage( m_pMWContext, m_csBackgroundImage, FALSE /*TRUE*/ ) )
{
((CButton*)GetDlgItem(IDC_BKGRND_USE_IMAGE))->SetCheck(0);
GetDlgItem(IDC_NO_SAVE_IMAGE)->EnableWindow(FALSE);
return FALSE;
}
GetDlgItem(IDC_NO_SAVE_IMAGE)->EnableWindow(TRUE);
// Send changed image back to editbox in case this is Apply usage
UpdateData(FALSE);
}
}
if( ((CButton*)GetDlgItem(IDC_BKGRND_USE_IMAGE))->GetCheck() &&
!m_csBackgroundImage.IsEmpty() )
{
wfe_ValidateImage( m_pMWContext, m_csBackgroundImage );
int iLastDot = m_csBackgroundImage.ReverseFind('.');
CString csExt;
if(iLastDot > 0)
csExt= m_csBackgroundImage.Mid(iLastDot);
//we must check to see if file is a bmp!
if (0 == csExt.CompareNoCase(".bmp"))
{
char *t_outputfilename=wfe_ConvertImage(m_csBackgroundImage.GetBuffer(0),(void *)this,m_pMWContext);
if (t_outputfilename)
{
m_csBackgroundImage=t_outputfilename;
wfe_ValidateImage( m_pMWContext, m_csBackgroundImage );
XP_FREE(t_outputfilename);
UpdateData(FALSE);//we need to update m_csImage!
}
else
return FALSE;
}
}
return TRUE;
}
void CTablePage::OnHelp()
{
NetHelp(HELP_TABLE_PROPS_TABLE);
}
void CTablePage::SetModified(BOOL bModified)
{
m_bModified = bModified;
// Set state of Apply button
CPropertyPage::SetModified(bModified);
}
void CTablePage::OnOK()
{
// never visited this page or no change -- don't bother
if(!m_bActivated || !m_bModified )
return;
EDT_BeginBatchChanges(m_pMWContext);
// Save background image
if ( m_pTableData->pBackgroundImage )
{
XP_FREE( m_pTableData->pBackgroundImage );
m_pTableData->pBackgroundImage = NULL;
}
if( ((CButton*)GetDlgItem(IDC_BKGRND_USE_IMAGE))->GetCheck() &&
!m_csBackgroundImage.IsEmpty() ){
m_pTableData->pBackgroundImage = XP_STRDUP(m_csBackgroundImage);
// Save state of flag from checkbox
m_pTableData->bBackgroundNoSave = m_bNoSave;
}
m_pTableData->iRows = m_iRows;
m_pTableData->iColumns = m_iColumns;
m_pTableData->bBorderWidthDefined = m_bBorderWidthDefined;
m_pTableData->iBorderWidth = m_iBorderWidth;
m_pTableData->iCellSpacing = m_iCellSpacing;
m_pTableData->iCellPadding = m_iCellPadding;
m_pTableData->bWidthDefined = m_bUseWidth;
m_pTableData->bWidthPercent = m_iWidthType == ED_PERCENT;
m_pTableData->iWidth = m_iWidth;
m_pTableData->bHeightDefined = m_bUseHeight;
m_pTableData->bHeightPercent = m_iHeightType == ED_PERCENT;
m_pTableData->iHeight = m_iHeight;
SetTableAlign(m_pTableData, m_iAlign);
SetColorHelper(m_bUseColor, m_crColor, &m_pTableData->pColorBackground);
EDT_SetTableData(m_pMWContext, m_pTableData);
// OK, we need to insert or remove a caption, as nescessary.
SetTableCaption(m_pMWContext, m_iCaption);
OkToClose(); // CancelToClose() doesn't work!
EDT_EndBatchChanges(m_pMWContext);
CPropertyPage::OnOK();
// These may be different as a result of Relayout during EDT_SetTableData()
// (Backend fixes up size data to reflect layout algorithms)
m_iWidth = m_pTableData->iWidth;
m_iHeight = m_pTableData->iHeight;
// Get possibly new size of parent because of Relayout
EDT_GetTableParentSize(m_pMWContext, FALSE, &m_iParentWidth, &m_iParentHeight);
// We don't use DDX with these so we don't get "not-integer" error messages
// Set flag to prevent changing the associated checkbox
m_bInternalChangeEditbox = TRUE;
UpdateWidthAndHeight(this, m_iWidth, m_iHeight);
m_bInternalChangeEditbox = FALSE;
m_bModified = FALSE;
}
void CTablePage::OnExtraHTML()
{
CExtraHTMLDlg dlg(this, &m_pTableData->pExtra, IDS_TABLE_TAG);
if( IDOK == dlg.DoModal() )
SetModified(TRUE);
}
// Shared message handler for controls that
// only need to change Apply state
void CTablePage::EnableApplyButton()
{
SetModified(TRUE);
}
void CTablePage::OnChangeBorder()
{
((CButton*)GetDlgItem(IDC_USE_BORDER))->SetCheck(1);
m_bBorderWidthDefined = TRUE;
SetModified(TRUE);
}
void CTablePage::OnChangeWidth()
{
if( !m_bInternalChangeEditbox )
{
SetModified(TRUE);
m_bUseWidth = TRUE;
((CButton*)GetDlgItem(IDC_OVERRIDE_WIDTH))->SetCheck(1);
}
}
void CTablePage::OnChangeWidthType()
{
// See if type has changed and we need to convert
// to opposite type (pixels <-> percent of parent)
int iWidthType = ((CComboBox*)GetDlgItem(IDC_WIDTH_PIX_OR_PERCENT))->GetCurSel();
if( iWidthType != m_iWidthType )
{
// Get current data from edit box before converting
// Note that validation uses NEW width type
if( ValidateWidthAndHeight(this, &m_iWidth, &m_iHeight, iWidthType, m_iHeightType) )
{
if( iWidthType )
// Convert previous from % to pixels
m_iWidth = (m_iWidth * m_iParentWidth ) / 100;
else
// Convert previous value from pixels to %
m_iWidth = (m_iWidth * 100) / m_iParentWidth;
// This will trigger OnChange for width,
// which will set the IDC_OVERRIDE_WIDTH checkbox
UpdateWidthAndHeight(this, m_iWidth, m_iHeight);
SetModified(TRUE);
}
m_iWidthType = iWidthType;
}
}
void CTablePage::OnChangeHeight()
{
if( !m_bInternalChangeEditbox )
{
SetModified(TRUE);
m_bUseHeight = TRUE;
((CButton*)GetDlgItem(IDC_OVERRIDE_HEIGHT))->SetCheck(1);
}
}
void CTablePage::OnChangeHeightType()
{
// See if type has changed and we need to convert
// to opposite type (pixels <-> percent of parent)
int iHeightType = ((CComboBox*)GetDlgItem(IDC_HEIGHT_PIX_OR_PERCENT))->GetCurSel();
if( iHeightType != m_iHeightType )
{
// Get current data from edit box before converting
// Note that validation uses NEW height type
if( ValidateWidthAndHeight(this, &m_iWidth, &m_iHeight, m_iWidthType, iHeightType) )
{
if( iHeightType )
// Convert previous from % to pixels
m_iHeight = (m_iHeight * m_iParentHeight ) / 100;
else
// Convert previous value from pixels to %
m_iHeight = (m_iHeight * 100) / m_iParentHeight;
// This will trigger OnChange for height,
// which will set the IDC_OVERRIDE_HEIGHT checkbox
UpdateWidthAndHeight(this, m_iWidth, m_iHeight);
SetModified(TRUE);
}
m_iHeightType = iHeightType;
}
}
void CTablePage::OnOverrideColor()
{
m_bUseColor = ((CButton*)GetDlgItem(IDC_OVERRIDE_COLOR))->GetCheck();
SetModified(TRUE);
}
void CTablePage::OnChooseColor()
{
// Get the combobox location so we popup new dialog just under it
RECT rect;
GetDlgItem(IDC_CHOOSE_COLOR)->GetWindowRect(&rect);
CColorPicker dlg(this, m_pMWContext, m_crColor, BACKGROUND_COLORREF, IDS_TABLE_BACKGROUND, &rect);
COLORREF crNew = dlg.GetColor();
if( crNew != CANCEL_COLORREF )
{
m_crColor = crNew;
if(m_crColor == DEFAULT_COLORREF){
m_crColor = prefInfo.m_rgbBackgroundColor;
}
m_bUseColor = TRUE;
((CButton*)GetDlgItem(IDC_OVERRIDE_COLOR))->SetCheck(m_bUseColor);
m_ColorButton.Update();
SetModified(TRUE);
}
}
void CTablePage::OnUseBkgrndImage()
{
int iUseImageBackground = ((CButton*)GetDlgItem(IDC_BKGRND_USE_IMAGE))->GetCheck();;
SetModified(TRUE);
if( iUseImageBackground )
{
// User decided to use the image, so do trigger validation
if( !m_csBackgroundImage.IsEmpty() &&
wfe_ValidateImage( m_pMWContext, m_csBackgroundImage, FALSE /*TRUE*/ ) )
{
((CButton*)GetDlgItem(IDC_BKGRND_USE_IMAGE))->SetCheck(1);
} else {
GetDlgItem(IDC_BKGRND_IMAGE)->SetFocus();
}
m_bValidImage = TRUE;
}
GetDlgItem(IDC_NO_SAVE_IMAGE)->EnableWindow(iUseImageBackground);
}
void CTablePage::OnChooseBkgrndImage()
{
UpdateData(TRUE);
char * szFilename = wfe_GetExistingImageFileName(this->m_hWnd,
szLoadString(IDS_SELECT_IMAGE), TRUE);
if ( szFilename == NULL )
return;
m_csBackgroundImage = szFilename;
if( wfe_ValidateImage( m_pMWContext, m_csBackgroundImage, FALSE /*TRUE*/ ) )
{
((CButton*)GetDlgItem(IDC_BKGRND_USE_IMAGE))->SetCheck(1);
GetDlgItem(IDC_NO_SAVE_IMAGE)->EnableWindow(TRUE);
} else {
((CButton*)GetDlgItem(IDC_BKGRND_USE_IMAGE))->SetCheck(0);
GetDlgItem(IDC_NO_SAVE_IMAGE)->EnableWindow(FALSE);
}
// Send new name to editbox
UpdateData(FALSE);
XP_FREE( szFilename );
m_bValidImage = TRUE;
m_bImageChanged = FALSE;
SetModified(TRUE);
}
void CTablePage::OnNoSave()
{
SetModified(TRUE);
}
void CTablePage::OnChangeBkgrndImage()
{
// Set flags to trigger validation
m_bValidImage = FALSE;
m_bImageChanged = TRUE;
UpdateData(TRUE);
CString csTemp = m_csBackgroundImage;
csTemp.TrimLeft();
csTemp.TrimRight();
// Set checkbox if there are any characters, clear if empty
((CButton*)GetDlgItem(IDC_BKGRND_USE_IMAGE))->SetCheck(!csTemp.IsEmpty());
if(!csTemp.IsEmpty())
GetDlgItem(IDC_NO_SAVE_IMAGE)->EnableWindow(TRUE);
SetModified(TRUE);
}
/////////////////////////////////////////////////////////////////
CTableCellPage::CTableCellPage(CWnd *pParent, MWContext * pMWContext,
CEditorResourceSwitcher * pResourceSwitcher,
EDT_TableCellData * pCellData,
UINT nIDCaption )
: CNetscapePropertyPage(CTableCellPage::IDD, nIDCaption),
m_bActivated(0),
m_pMWContext(pMWContext),
m_pResourceSwitcher(pResourceSwitcher),
m_pCellData(pCellData),
m_bCustomColor(0),
m_crColor(DEFAULT_COLORREF),
m_iParentWidth(0),
m_iParentHeight(0),
m_bInternalChangeEditbox(0)
{
ASSERT(pMWContext);
//{{AFX_DATA_INIT(CPage)
m_iAlign = -1;
m_iVAlign = -1;
m_iColumnSpan = 0;
m_iUseColor = 0;
m_iUseHeight = 0;
m_iUseWidth = 0;
m_iHeader = FALSE;
m_iHeight = 1;
m_iHeightType = 0;
m_iWidthType = 0;
m_iRowSpan = 0;
m_iWidth = 1;
m_iNoWrap = 1;
m_csBackgroundImage = _T("");
m_bNoSave = 0;
//}}AFX_DATA_INIT
#ifdef XP_WIN32
// Set the hInstance so we get template from editor's resource DLL
m_psp.hInstance = AfxGetResourceHandle();
#endif
}
CTableCellPage::~CTableCellPage()
{
if( m_pCellData )
EDT_FreeTableCellData(m_pCellData);
}
void CTableCellPage::DoDataExchange(CDataExchange* pDX)
{
CPropertyPage::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CTableCellPage)
DDX_Text(pDX, IDC_ROWSPAN, m_iRowSpan);
DDV_MinMaxInt(pDX, m_iRowSpan, 1, 100);
DDX_Text(pDX, IDC_COLSPAN, m_iColumnSpan);
DDV_MinMaxInt(pDX, m_iColumnSpan, 1, 100);
DDX_CBIndex(pDX, IDC_TABLE_CELL_ALIGN, m_iAlign);
DDX_CBIndex(pDX, IDC_TABLE_CELL_VALIGN, m_iVAlign);
DDX_Check(pDX, IDC_OVERRIDE_COLOR, m_iUseColor);
DDX_Check(pDX, IDC_OVERRIDE_HEIGHT, m_iUseHeight);
DDX_Check(pDX, IDC_OVERRIDE_WIDTH, m_iUseWidth);
DDX_Check(pDX, IDC_HEADER, m_iHeader);
DDX_Check(pDX, IDC_WRAP, m_iNoWrap);
DDX_CBIndex(pDX, IDC_WIDTH_PIX_OR_PERCENT, m_iWidthType);
DDX_CBIndex(pDX, IDC_HEIGHT_PIX_OR_PERCENT, m_iHeightType);
DDX_Text(pDX, IDC_BKGRND_IMAGE, m_csBackgroundImage);
DDX_Check(pDX, IDC_NO_SAVE_IMAGE, m_bNoSave);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CTableCellPage, CNetscapePropertyPage)
//{{AFX_MSG_MAP(CTableCellPage)
ON_EN_CHANGE(IDC_ROWSPAN, EnableApplyButton)
ON_EN_CHANGE(IDC_COLSPAN, EnableApplyButton)
ON_BN_CLICKED(IDC_HEADER, EnableApplyButton)
ON_BN_CLICKED(IDC_WRAP, EnableApplyButton)
ON_CBN_SELCHANGE(IDC_TABLE_CELL_ALIGN, OnChangeHAlign)
ON_CBN_SELCHANGE(IDC_TABLE_CELL_VALIGN, OnChangeVAlign)
ON_BN_CLICKED(IDC_OVERRIDE_WIDTH, EnableApplyButton)
ON_EN_CHANGE(IDC_WIDTH, OnChangeWidth)
ON_CBN_SELCHANGE(IDC_WIDTH_PIX_OR_PERCENT, OnChangeWidthType)
ON_BN_CLICKED(IDC_OVERRIDE_HEIGHT, EnableApplyButton)
ON_EN_CHANGE(IDC_HEIGHT, OnChangeHeight)
ON_CBN_SELCHANGE(IDC_HEIGHT_PIX_OR_PERCENT, OnChangeHeightType)
ON_BN_CLICKED(IDC_OVERRIDE_COLOR, OnOverrideColor)
ON_BN_CLICKED(IDC_CHOOSE_COLOR, OnChooseColor)
ON_BN_CLICKED(IDC_EXTRA_HTML, OnExtraHTML)
ON_BN_CLICKED(IDC_BKGRND_USE_IMAGE, OnUseBkgrndImage)
ON_EN_CHANGE(IDC_BKGRND_IMAGE, OnChangeBkgrndImage)
ON_BN_CLICKED(IDC_CHOOSE_BACKGROUND, OnChooseBkgrndImage)
ON_BN_CLICKED(IDC_NO_SAVE_IMAGE, EnableApplyButton)
ON_BN_CLICKED(IDC_PREVIOUS, OnPrevious)
ON_BN_CLICKED(IDC_NEXT, OnNext)
ON_CBN_SELCHANGE(IDC_TABLE_SELECTION_TYPE, OnChangeSelectionType)
ON_BN_CLICKED(IDC_INSERT, OnInsert)
ON_BN_CLICKED(IDC_DELETE, OnDelete)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
BOOL CTableCellPage::OnSetActive()
{
if(m_pResourceSwitcher && !m_bActivated)
{
// We must be sure we have switched
// the first time here - before dialog creation
m_pResourceSwitcher->switchResources();
// This is usually supplied, but lets be sure
if( !m_pCellData )
m_pCellData = EDT_GetTableCellData(m_pMWContext);
if( !m_pCellData )
return FALSE;
}
if(!CPropertyPage::OnSetActive())
return FALSE;
if( m_bActivated )
{
// We are activating the pane after switching to table tab and back again
// Refresh cell data to get possibly-changed width and/or height
EDT_FreeTableCellData(m_pCellData);
m_pCellData = EDT_GetTableCellData(m_pMWContext);
m_iWidth = CASTINT(m_pCellData->iWidth);
m_iHeight = CASTINT(m_pCellData->iHeight);
m_iWidthType = m_pCellData->bWidthPercent ? ED_PERCENT : ED_PIXELS;
m_iHeightType = m_pCellData->bHeightPercent ? ED_PERCENT : ED_PIXELS;
m_iUseWidth = InitCheckbox(IDC_OVERRIDE_WIDTH, CF_WIDTH, m_pCellData->bWidthDefined);
m_iUseHeight = InitCheckbox(IDC_OVERRIDE_HEIGHT, CF_HEIGHT, m_pCellData->bHeightDefined);
// We don't use DDX with these so we don't get "not-integer" error messages
// Set flag to prevent changing the associated checkbox
m_bInternalChangeEditbox = TRUE;
UpdateWidthAndHeight(this, m_iWidth, m_iHeight);
m_bInternalChangeEditbox = FALSE;
UpdateData(FALSE);
return(TRUE);
}
m_bActivated = TRUE;
// Get these strings from the editor resource dll before we switch back
m_csSingleCell.LoadString(IDS_SINGLE_CELL_CAPTION);
m_csSelectedCells.LoadString(IDS_SELECTED_CELLS_CAPTION);
m_csSelectedRow.LoadString(IDS_SELECTED_ROW_CAPTION);
m_csSelectedCol.LoadString(IDS_SELECTED_COLUMN_CAPTION);
// Switch back to EXE's resources
if( m_pResourceSwitcher )
m_pResourceSwitcher->Reset();
if( !m_ColorButton.Subclass(this, IDC_CHOOSE_COLOR, &m_crColor) )
return FALSE;
((CEdit*)GetDlgItem(IDC_ROWSPAN))->LimitText(3);
((CEdit*)GetDlgItem(IDC_COLSPAN))->LimitText(3);
// Initialize Horizontal and Vertical Alignment listboxes
CComboBox *pCombo = (CComboBox*)GetDlgItem(IDC_TABLE_CELL_ALIGN);
pCombo->AddString(szLoadString(IDS_LEFT));
pCombo->AddString(szLoadString(IDS_CENTER));
pCombo->AddString(szLoadString(IDS_RIGHT));
pCombo = (CComboBox*)GetDlgItem(IDC_TABLE_CELL_VALIGN);
pCombo->AddString(szLoadString(IDS_TOP));
pCombo->AddString(szLoadString(IDS_CENTER));
pCombo->AddString(szLoadString(IDS_BOTTOM));
//pCombo->AddString(szLoadString(IDS_BASELINE));
// Initialize width and height Units comboboxex
pCombo = (CComboBox*)GetDlgItem(IDC_HEIGHT_PIX_OR_PERCENT);
char *pPercent = szLoadString(CASTUINT(EDT_IsInsertPointInNestedTable(m_pMWContext) ? IDS_PERCENT_PARENT_CELL : IDS_PERCENT_TABLE));
pCombo->AddString(szLoadString(IDS_PIXELS));
pCombo->AddString(pPercent);
pCombo = (CComboBox*)GetDlgItem(IDC_WIDTH_PIX_OR_PERCENT);
pCombo->AddString(szLoadString(IDS_PIXELS));
pCombo->AddString(pPercent);
pCombo = (CComboBox*)GetDlgItem(IDC_TABLE_SELECTION_TYPE);
pCombo->AddString(szLoadString(IDS_CELL));
pCombo->AddString(szLoadString(IDS_ROW));
pCombo->AddString(szLoadString(IDS_COLUMN));
// Get size of parent to convert % values to pixels and vice versa
// TRUE = get size of current cell's parent, table, minus border and inter-cell space
// Use to convert pixels to "% of parent"
EDT_GetTableParentSize(m_pMWContext, TRUE, &m_iParentWidth, &m_iParentHeight);
// Initialize all controls based on cell data
InitPageData();
return(TRUE);
}
void CTableCellPage::InitPageData()
{
// Set currently-selected align items in comboboxes
CComboBox *pCombo = (CComboBox*)GetDlgItem(IDC_TABLE_CELL_ALIGN);
if( m_pCellData->mask & CF_ALIGN )
{
m_iAlign = kXPToFEAlign[m_pCellData->align+1];
// Remove "Don't change" item in combo if already there
if( pCombo->GetCount() == 4 )
pCombo->DeleteString(3);
}
else
{
m_iAlign = -1; // Empty combox = mixed styles
// Add "Dont change" item to combo if not already there
if( pCombo->GetCount() == 3 )
pCombo->AddString(ed_pDontChange);
}
// Vertical alignment
pCombo = (CComboBox*)GetDlgItem(IDC_TABLE_CELL_VALIGN);
if( m_pCellData->mask & CF_VALIGN )
{
m_iVAlign = kXPToFEVAlign[m_pCellData->valign+1];
// Remove "Dont change" item in combo if already there
if( pCombo->GetCount() == 4 )
pCombo->DeleteString(3);
}
else
{
m_iVAlign = -1;
// Add "Dont change" item to combo if not already there
if( pCombo->GetCount() == 3 )
pCombo->AddString(ed_pDontChange);
}
m_iColumnSpan = CASTINT(m_pCellData->iColSpan);
m_iRowSpan = CASTINT(m_pCellData->iRowSpan);
// Disable ColSpan and RowSpan if multiple cells selected
GetDlgItem(IDC_COLSPAN)->EnableWindow(m_pCellData->mask & CF_COLSPAN);
GetDlgItem(IDC_ROWSPAN)->EnableWindow(m_pCellData->mask & CF_ROWSPAN);
m_iHeader = InitCheckbox(IDC_HEADER, CF_HEADER, m_pCellData->bHeader);
m_iNoWrap = InitCheckbox(IDC_WRAP, CF_NOWRAP, m_pCellData->bNoWrap);
m_iWidth = CASTINT(m_pCellData->iWidth);
m_iWidthType = m_pCellData->bWidthPercent ? ED_PERCENT : ED_PIXELS;
m_iHeight = CASTINT(m_pCellData->iHeight);
m_iHeightType = m_pCellData->bHeightPercent ? ED_PERCENT : ED_PIXELS;
// We don't use DDX with these so we don't get "not-integer" error messages
// Set flag to prevent changing the associated checkbox
m_bInternalChangeEditbox = TRUE;
UpdateWidthAndHeight(this, m_iWidth, m_iHeight);
m_bInternalChangeEditbox = FALSE;
m_iUseWidth = InitCheckbox(IDC_OVERRIDE_WIDTH, CF_WIDTH, m_pCellData->bWidthDefined);
m_iUseHeight = InitCheckbox(IDC_OVERRIDE_HEIGHT, CF_HEIGHT, m_pCellData->bHeightDefined);
BOOL bUseColor;
GetColorHelper(m_pCellData->pColorBackground, bUseColor, m_crColor);
m_iUseColor = InitCheckbox(IDC_OVERRIDE_COLOR, CF_BACK_COLOR, bUseColor);
m_csBackgroundImage = m_pCellData->pBackgroundImage;
BOOL bHaveImage = !m_csBackgroundImage.IsEmpty();
((CButton*)GetDlgItem(IDC_BKGRND_USE_IMAGE))->SetCheck(1);
int iUseImage = InitCheckbox(IDC_BKGRND_USE_IMAGE, CF_BACK_IMAGE, bHaveImage);
((CButton*)GetDlgItem(IDC_BKGRND_USE_IMAGE))->SetCheck(iUseImage);
if( iUseImage == 1 && m_iUseColor == 1 )
{
// Clear the current color checkbox ONLY
// if we were sure about using image
// we were going to use color
m_iUseColor = 0;
((CButton*)GetDlgItem(IDC_OVERRIDE_COLOR))->SetCheck(0);
}
// Disable original location checkbox if using color
if( m_iUseColor )
{
GetDlgItem(IDC_NO_SAVE_IMAGE)->EnableWindow(FALSE);
}
// Flag to leave image at original location and not save with page
m_bNoSave = m_pCellData->bBackgroundNoSave;
// Get type of cell set selected and set combobox
m_iSelectionType = m_pCellData->iSelectionType;
// Not sure if this is needed????
if( m_iSelectionType != ED_HIT_SEL_ROW && m_iSelectionType != ED_HIT_SEL_COL )
{
m_iSelectionType = ED_HIT_SEL_CELL;
}
pCombo = (CComboBox*)GetDlgItem(IDC_TABLE_SELECTION_TYPE);
pCombo->SetCurSel(kXPToFESelType[m_iSelectionType]);
// SetPageTitle only works in Win32
// How do we set tab text in Win16?
// Maybe set m_strCaption directly?
CNetscapePropertySheet *pSheet = (CNetscapePropertySheet*)GetParent();
if( m_pCellData->iSelectedCount > 1 )
{
switch( m_iSelectionType )
{
case ED_HIT_SEL_COL:
pSheet->SetPageTitle(1, m_csSelectedCol);
break;
case ED_HIT_SEL_ROW:
pSheet->SetPageTitle(1, m_csSelectedRow);
break;
default:
pSheet->SetPageTitle(1, m_csSelectedCells);
break;
}
} else {
pSheet->SetPageTitle(1, m_csSingleCell);
}
// Send rest of the data to controls
UpdateData(FALSE);
// Gray out the APPLY button
SetModified(FALSE);
// Force redrawing entire page
Invalidate(FALSE);
}
int CTableCellPage::InitCheckbox(UINT nIDCheckbox, ED_CellFormat cf, BOOL bSetState)
{
int iState;
CButton *pButton = ((CButton*)GetDlgItem(nIDCheckbox));
// Get current style but clear all relevant button-style bits
UINT nStyle = CASTUINT(pButton->GetButtonStyle() & 0xFFFFFFF0L);
if( m_pCellData->mask & cf )
{
// We know the style, so we can use 2-state boxes
nStyle |= BS_AUTOCHECKBOX;
iState = bSetState ? 1 : 0;
} else
{
// We don't know the style, so we use 3-state boxes
// so user can return to the "don't change" state
nStyle |= BS_AUTO3STATE;
// Set initial value to the indeterminate state
iState = 2;
}
pButton->SetButtonStyle(nStyle);
return iState;
}
// Called before OnOK to do validation
BOOL CTableCellPage::OnKillActive()
{
// never visited this page or no change -- don't bother
if(!m_bActivated || !m_bModified )
return TRUE;
if ( !UpdateData(TRUE) ||
!ValidateWidthAndHeight(this, &m_iWidth, &m_iHeight, m_iWidthType, m_iHeightType) )
{
return FALSE;
}
if ( !m_csBackgroundImage.IsEmpty() )
{
if ( m_bImageChanged && !m_bValidImage )
{
if( ((CButton*)GetDlgItem(IDC_BKGRND_USE_IMAGE))->GetCheck() == 1 &&
!wfe_ValidateImage( m_pMWContext, m_csBackgroundImage, FALSE ) )
{
((CButton*)GetDlgItem(IDC_BKGRND_USE_IMAGE))->SetCheck(0);
GetDlgItem(IDC_NO_SAVE_IMAGE)->EnableWindow(FALSE);
return FALSE;
}
// Send changed image back to editbox in case this is Apply usage
UpdateData(FALSE);
}
}
if( ((CButton*)GetDlgItem(IDC_BKGRND_USE_IMAGE))->GetCheck() == 1 &&
!m_csBackgroundImage.IsEmpty() )
{
wfe_ValidateImage( m_pMWContext, m_csBackgroundImage );
int iLastDot = m_csBackgroundImage.ReverseFind('.');
CString csExt;
if(iLastDot > 0)
csExt= m_csBackgroundImage.Mid(iLastDot);
//we must check to see if file is a bmp!
if (0 == csExt.CompareNoCase(".bmp"))
{
char *t_outputfilename=wfe_ConvertImage(m_csBackgroundImage.GetBuffer(0),(void *)this,m_pMWContext);
if (t_outputfilename)
{
m_csBackgroundImage=t_outputfilename;
wfe_ValidateImage( m_pMWContext, m_csBackgroundImage );
XP_FREE(t_outputfilename);
UpdateData(FALSE);//we need to update m_csImage!
}
else
return FALSE;
}
}
return TRUE;
}
void CTableCellPage::SetModified(BOOL bModified)
{
m_bModified = bModified;
// Change state of Apply button
CPropertyPage::SetModified(bModified);
}
void CTableCellPage::OnOK()
{
// never visited this page or no change -- don't bother
if(!m_bActivated || !m_bModified )
return;
// Use checkbox states and set/clear mask bits and data appropriately
// This checkbox is not hooked up to DDX
int iCheckState = ((CButton*)GetDlgItem(IDC_BKGRND_USE_IMAGE))->GetCheck();
// Clear background image unless we shouldn't change it
if( iCheckState != 2 )
XP_FREEIF( m_pCellData->pBackgroundImage );
if( iCheckState == 1 &&
!m_csBackgroundImage.IsEmpty() )
{
m_pCellData->pBackgroundImage = XP_STRDUP(m_csBackgroundImage);
// Save state of flag from checkbox
m_pCellData->bBackgroundNoSave = m_bNoSave;
}
if( m_iAlign == -1 )
{
// Don't change this attribute
FE_CLEAR_BIT(m_pCellData->mask, CF_ALIGN);
} else {
// We are sure user wants to set this
FE_SET_BIT(m_pCellData->mask, CF_ALIGN);
}
m_pCellData->align = kFEToXPAlign[m_iAlign];
if( m_iVAlign == -1 )
{
FE_CLEAR_BIT(m_pCellData->mask, CF_VALIGN);
} else {
FE_SET_BIT(m_pCellData->mask, CF_VALIGN);
}
m_pCellData->valign = kFEToXPVAlign[m_iVAlign];
// These can't change if disabled, so it doesn't
// hurt to get values no matter what
m_pCellData->iColSpan = m_iColumnSpan;
m_pCellData->iRowSpan = m_iRowSpan;
if( m_iUseColor == 2 )
{
FE_CLEAR_BIT(m_pCellData->mask, CF_BACK_COLOR);
} else {
FE_SET_BIT(m_pCellData->mask, CF_BACK_COLOR);
SetColorHelper(m_iUseColor == 1, m_crColor, &m_pCellData->pColorBackground);
}
if( m_iHeader == 2 )
{
FE_CLEAR_BIT(m_pCellData->mask, CF_HEADER);
} else {
FE_SET_BIT(m_pCellData->mask, CF_HEADER);
m_pCellData->bHeader = m_iHeader > 0;
}
if( m_iNoWrap == 2 )
{
FE_CLEAR_BIT(m_pCellData->mask, CF_NOWRAP);
} else {
FE_SET_BIT(m_pCellData->mask, CF_NOWRAP);
m_pCellData->bNoWrap = m_iNoWrap > 0;
}
if( m_iUseHeight == 2 )
{
FE_CLEAR_BIT(m_pCellData->mask, CF_HEIGHT);
} else {
FE_SET_BIT(m_pCellData->mask, CF_HEIGHT);
m_pCellData->iHeight = m_iHeight;
m_pCellData->bHeightPercent = (m_iHeightType == ED_PERCENT);
}
m_pCellData->bHeightDefined = (m_iUseHeight == 1);
if( m_iUseWidth == 2 )
{
FE_CLEAR_BIT(m_pCellData->mask, CF_WIDTH);
} else {
FE_SET_BIT(m_pCellData->mask, CF_WIDTH);
m_pCellData->iWidth = m_iWidth;
m_pCellData->bWidthPercent = (m_iWidthType == ED_PERCENT);
}
m_pCellData->bWidthDefined = (m_iUseWidth == 1);
EDT_SetTableCellData(m_pMWContext, m_pCellData);
// TODO: WE MAY NOT NEED THIS AFTER NEW LAYOUT WORK
// We must call this here else special selection is lost
EDT_StartSpecialCellSelection(m_pMWContext, m_pCellData);
OkToClose(); // CancelToClose() doesn't work!
CPropertyPage::OnOK();
// These may be different as a result of Relayout during EDT_SetTableData()
// (Backend fixes up size data to reflect layout algorithms)
m_iWidth = m_pCellData->iWidth;
m_iHeight = m_pCellData->iHeight;
// Get possibly new size of parent because of Relayout
EDT_GetTableParentSize(m_pMWContext, TRUE, &m_iParentWidth, &m_iParentHeight);
// We don't use DDX with these so we don't get "not-integer" error messages
// Set flag to prevent changing the associated checkbox
m_bInternalChangeEditbox = TRUE;
UpdateWidthAndHeight(this, m_iWidth, m_iHeight);
m_bInternalChangeEditbox = FALSE;
m_bModified = FALSE;
}
void CTableCellPage::OnChangeSelectionType()
{
CComboBox *pCombo = (CComboBox*)GetDlgItem(IDC_TABLE_SELECTION_TYPE);
// Get selection type from combobox
m_iSelectionType = kFEToXPSelType[pCombo->GetCurSel()];
// Change selection, but don't move focus cell
ChangeSelection(ED_MOVE_NONE);
}
void CTableCellPage::ChangeSelection(ED_MoveSelType iMoveType)
{
// Save current data
if( OnKillActive() )
{
OnOK();
} else {
return;
}
EDT_ChangeTableSelection(m_pMWContext, m_iSelectionType, iMoveType, m_pCellData);
InitPageData();
}
void CTableCellPage::OnPrevious()
{
ChangeSelection(ED_MOVE_PREV);
}
void CTableCellPage::OnNext()
{
ChangeSelection(ED_MOVE_NEXT);
}
void CTableCellPage::OnHelp()
{
NetHelp(HELP_TABLE_PROPS_CELL);
}
void CTableCellPage::OnExtraHTML()
{
CExtraHTMLDlg dlg(this, &m_pCellData->pExtra, IDS_TD_TAG);
if( IDOK == dlg.DoModal() )
{
SetModified(TRUE);
}
}
void CTableCellPage::OnChangeWidth()
{
if( !m_bInternalChangeEditbox )
{
SetModified(TRUE);
m_iUseWidth = TRUE;
((CButton*)GetDlgItem(IDC_OVERRIDE_WIDTH))->SetCheck(1);
}
}
void CTableCellPage::OnChangeWidthType()
{
// See if type has changed and we need to convert
// to opposite type (pixels <-> percent of parent)
int iWidthType = ((CComboBox*)GetDlgItem(IDC_WIDTH_PIX_OR_PERCENT))->GetCurSel();
if( iWidthType != m_iWidthType )
{
// Get current data from edit box before converting
// Note that validation uses NEW width type
if( ValidateWidthAndHeight(this, &m_iWidth, &m_iHeight, iWidthType, m_iHeightType) )
{
if( iWidthType )
{
// New type = %
// Convert previous value from pixels to %
m_iWidth = (m_iWidth * 100) / m_iParentWidth;
} else {
// New type = pixels
// Convert previous from % to pixels
m_iWidth = (m_iWidth * m_iParentWidth ) / 100;
}
UpdateWidthAndHeight(this, m_iWidth, m_iHeight);
SetModified(TRUE);
}
m_iWidthType = iWidthType;
}
}
void CTableCellPage::OnChangeHeight()
{
if( !m_bInternalChangeEditbox )
{
SetModified(TRUE);
m_iUseHeight = 1;
((CButton*)GetDlgItem(IDC_OVERRIDE_HEIGHT))->SetCheck(1);
}
}
void CTableCellPage::OnChangeHeightType()
{
// See if type has changed and we need to convert
// to opposite type (pixels <-> percent of parent)
int iHeightType = ((CComboBox*)GetDlgItem(IDC_HEIGHT_PIX_OR_PERCENT))->GetCurSel();
if( iHeightType != m_iHeightType )
{
// Get current data from edit box before converting
// Note that validation uses NEW height type
if( ValidateWidthAndHeight(this, &m_iWidth, &m_iHeight, m_iWidthType, iHeightType) )
{
if( iHeightType )
// Convert previous from % to pixels
m_iHeight = (m_iHeight * m_iParentHeight ) / 100;
else
// Convert previous value from pixels to %
m_iHeight = (m_iHeight * 100) / m_iParentHeight;
UpdateWidthAndHeight(this, m_iWidth, m_iHeight);
SetModified(TRUE);
}
m_iHeightType = iHeightType;
}
}
void CTableCellPage::OnOverrideColor()
{
m_iUseColor = ((CButton*)GetDlgItem(IDC_OVERRIDE_COLOR))->GetCheck();
SetModified(TRUE);
}
void CTableCellPage::OnChooseColor()
{
// Get the combobox location so we popup new dialog just under it
RECT rect;
GetDlgItem(IDC_CHOOSE_COLOR)->GetWindowRect(&rect);
CColorPicker dlg(this, m_pMWContext, m_crColor, BACKGROUND_COLORREF, IDS_CELL_BACKGROUND, &rect);
COLORREF crNew = dlg.GetColor();
if( crNew != CANCEL_COLORREF )
{
m_crColor = crNew;
if(m_crColor == DEFAULT_COLORREF)
{
m_crColor = prefInfo.m_rgbBackgroundColor;
}
m_iUseColor = 1;
((CButton*)GetDlgItem(IDC_OVERRIDE_COLOR))->SetCheck(m_iUseColor);
m_ColorButton.Update();
SetModified(TRUE);
}
}
void CTableCellPage::OnUseBkgrndImage()
{
int iUseImageBackground = ((CButton*)GetDlgItem(IDC_BKGRND_USE_IMAGE))->GetCheck();;
SetModified(TRUE);
if( iUseImageBackground )
{
// User decided to use the image, so do trigger validation
if( !m_csBackgroundImage.IsEmpty() &&
wfe_ValidateImage( m_pMWContext, m_csBackgroundImage, FALSE /*TRUE*/ ) )
{
((CButton*)GetDlgItem(IDC_BKGRND_USE_IMAGE))->SetCheck(1);
} else {
GetDlgItem(IDC_BKGRND_IMAGE)->SetFocus();
}
m_bValidImage = TRUE;
}
GetDlgItem(IDC_NO_SAVE_IMAGE)->EnableWindow(iUseImageBackground);
}
void CTableCellPage::OnChooseBkgrndImage()
{
UpdateData(TRUE);
char * szFilename = wfe_GetExistingImageFileName(this->m_hWnd,
szLoadString(IDS_SELECT_IMAGE), TRUE);
if ( szFilename == NULL )
return;
m_csBackgroundImage = szFilename;
if( wfe_ValidateImage( m_pMWContext, m_csBackgroundImage, FALSE /*TRUE*/ ) )
{
((CButton*)GetDlgItem(IDC_BKGRND_USE_IMAGE))->SetCheck(1);
GetDlgItem(IDC_NO_SAVE_IMAGE)->EnableWindow(TRUE);
} else {
((CButton*)GetDlgItem(IDC_BKGRND_USE_IMAGE))->SetCheck(0);
GetDlgItem(IDC_NO_SAVE_IMAGE)->EnableWindow(FALSE);
}
// Send new name to editbox
UpdateData(FALSE);
XP_FREE( szFilename );
m_bValidImage = TRUE;
m_bImageChanged = FALSE;
SetModified(TRUE);
}
void CTableCellPage::OnChangeBkgrndImage()
{
// Set flags to trigger validation
m_bValidImage = FALSE;
m_bImageChanged = TRUE;
UpdateData(TRUE);
CString csTemp = m_csBackgroundImage;
csTemp.TrimLeft();
csTemp.TrimRight();
// Set checkbox if there are any characters, clear if empty
((CButton*)GetDlgItem(IDC_BKGRND_USE_IMAGE))->SetCheck(!csTemp.IsEmpty());
if(!csTemp.IsEmpty())
{
GetDlgItem(IDC_NO_SAVE_IMAGE)->EnableWindow(TRUE);
}
SetModified(TRUE);
}
void CTableCellPage::OnChangeHAlign()
{
SetModified(TRUE);
// When user selects last item ("Don't change"),
// change selected item to empty combobox
CComboBox *pCombo = (CComboBox*)GetDlgItem(IDC_TABLE_CELL_ALIGN);
m_iAlign = pCombo->GetCurSel();
if( m_iAlign == 3 )
{
m_iAlign = -1;
pCombo->SetCurSel(-1);
}
}
void CTableCellPage::OnChangeVAlign()
{
SetModified(TRUE);
CComboBox *pCombo = (CComboBox*)GetDlgItem(IDC_TABLE_CELL_VALIGN);
m_iVAlign = pCombo->GetCurSel();
if( m_iVAlign == 4 )
{
m_iVAlign = -1;
pCombo->SetCurSel(-1);
}
}
void CTableCellPage::OnInsert()
{
//TODO: ADD INSERT DIALOG
}
void CTableCellPage::OnDelete()
{
//TODO: ADD DELETE DIALOG
}
// Shared message handler for controls that
// only need to change Apply state
void CTableCellPage::EnableApplyButton()
{
SetModified(TRUE);
}
/////////////////////////////////////////////////////////////////