2020-09-30 17:12:29 +02:00

1119 lines
28 KiB
C++

/************************************************************************
* *
* CNTEDIT.CPP *
* *
* Copyright (C) Microsoft Corporation 1995 *
* All Rights reserved. *
* *
************************************************************************/
#include "stdafx.h"
#include "resource.h"
#pragma hdrstop
#include <ctype.h>
#include "..\common\cbrdcast.h"
#include "cntdoc.h"
#include "cntview.h"
#include "editcont.h"
#include "dlgindex.h"
#include "dlglink.h"
#include "addalias.h"
#include <string.h>
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
struct FRSTATE // Find/Replace for CEditView
{
CFindReplaceDialog* pFindReplaceDlg; // find or replace dialog
BOOL bFindOnly; // Is pFindReplace the find or replace?
CString strFind; // last find string
CString strReplace; // last replace string
BOOL bCase; // TRUE==case sensitive, FALSE==not
int bNext; // TRUE==search down, FALSE== search up
FRSTATE();
};
FRSTATE::FRSTATE()
{
pFindReplaceDlg = NULL;
bCase = FALSE;
bNext = TRUE;
}
static char szFINDMSGSTRING[] = FINDMSGSTRING;
static const UINT nMsgFindReplace = ::RegisterWindowMessage(szFINDMSGSTRING);
static PSTR STDCALL FindEqual(PCSTR pszLine);
static FRSTATE _afxLastFRState;
/////////////////////////////////////////////////////////////////////////////
// CCntEditView
IMPLEMENT_DYNCREATE(CCntEditView, CFormView)
BEGIN_MESSAGE_MAP(CCntEditView, CFormView)
//{{AFX_MSG_MAP(CCntEditView)
ON_BN_CLICKED(IDC_BUTTON_EDIT, OnButtonEdit)
ON_BN_CLICKED(IDEDIT_DIR_NAME, OnButtonEditFileName)
ON_BN_CLICKED(IDC_BUTTON_INDEX, OnButtonIndex)
ON_BN_CLICKED(IDC_BUTTON_INS_ABOVE, OnButtonInsAbove)
ON_BN_CLICKED(IDC_BUTTON_INS_BELOW, OnButtonInsBelow)
ON_BN_CLICKED(IDC_BUTTON_LINKS, OnButtonLinks)
ON_BN_CLICKED(IDC_BUTTON_REDUCE_LEVEL, OnButtonMoveLeft)
ON_BN_CLICKED(IDC_BUTTON_INCREASE_LEVEL, OnButtonMoveRight)
ON_BN_CLICKED(IDC_BUTTON_REMOVE, OnButtonRemove)
ON_BN_CLICKED(IDC_BUTTON_SEARCH, OnButtonSearch)
ON_BN_CLICKED(IDC_BUTTON_TABS, OnButtonTabs)
ON_EN_CHANGE(IDC_EDIT_BASE_FILE, OnChangeEditBaseFile)
ON_EN_CHANGE(IDC_EDIT_HELP_TITLE, OnChangeEditHelpTitle)
ON_LBN_DBLCLK(IDC_LIST_CONTENTS, OnDblclkListContents)
ON_BN_CLICKED(IDM_HELP_CNT, OnHelp)
ON_LBN_SELCHANGE(IDC_LIST_CONTENTS, OnSelchangeListContents)
ON_COMMAND(IDM_TRANSLATOR, OnTranslator)
ON_COMMAND(IDM_UNDO, OnUndo)
ON_UPDATE_COMMAND_UI(IDM_TRANSLATOR, OnUpdateTranslator)
ON_UPDATE_COMMAND_UI(IDM_UNDO, OnUpdateUndo)
ON_UPDATE_COMMAND_UI(IDM_REMOVE, OnUpdateTranslation)
ON_COMMAND(IDM_EDIT, OnButtonEdit)
ON_COMMAND(IDM_REMOVE, OnButtonRemove)
ON_COMMAND(IDM_INS_ABOVE, OnButtonInsAbove)
ON_COMMAND(IDM_INS_BELOW, OnButtonInsBelow)
ON_COMMAND(IDM_INCREASE_LEVEL, OnButtonMoveRight)
ON_COMMAND(IDM_DECREASE_LEVEL, OnButtonMoveLeft)
ON_COMMAND(IDM_FIND, OnButtonSearch)
ON_COMMAND(IDM_INDEX_FILES, OnButtonIndex)
ON_COMMAND(IDM_LINK_FILES, OnButtonLinks)
ON_COMMAND(IDM_TABS, OnButtonTabs)
ON_UPDATE_COMMAND_UI(IDM_INS_ABOVE, OnUpdateTranslation)
ON_UPDATE_COMMAND_UI(IDM_INS_BELOW, OnUpdateTranslation)
ON_UPDATE_COMMAND_UI(IDM_INCREASE_LEVEL, OnUpdateTranslation)
ON_UPDATE_COMMAND_UI(IDM_DECREASE_LEVEL, OnUpdateTranslation)
ON_UPDATE_COMMAND_UI(IDM_LINK_FILES, OnUpdateTranslation)
ON_WM_SIZE()
//}}AFX_MSG_MAP
ON_REGISTERED_MESSAGE(nMsgFindReplace, OnFindReplaceCmd)
ON_MESSAGE(WM_CONTEXTMENU, OnContextMenu)
ON_MESSAGE(WM_HELP, OnF1Help)
END_MESSAGE_MAP()
static const DWORD aHelpIds[] = {
IDC_EDIT_HELP_TITLE, IDH_EDIT_HELP_TITLE,
IDC_EDIT_BASE_FILE, IDH_EDIT_BASE_FILE,
IDC_LIST_CONTENTS, IDH_LIST_CONTENTS,
IDC_BUTTON_EDIT, IDH_CONTENTS_BUTTON_EDIT,
IDC_BUTTON_REMOVE, IDH_CONTENTS_BUTTON_REMOVE,
IDC_BUTTON_INS_ABOVE, IDH_BUTTON_INS_ABOVE,
IDC_BUTTON_INS_BELOW, IDH_BUTTON_INS_BELOW,
IDC_BUTTON_REDUCE_LEVEL, IDH_BUTTON_REDUCE_LEVEL,
IDC_BUTTON_INCREASE_LEVEL, IDH_BUTTON_INCREASE_LEVEL,
IDC_BUTTON_SEARCH, IDH_BUTTON_SEARCH,
IDC_BUTTON_INDEX, IDH_BUTTON_INDEX,
IDC_BUTTON_LINKS, IDH_BUTTON_LINKS,
IDC_BUTTON_TABS, IDH_BUTTON_TABS,
0, 0
};
CCntEditView::CCntEditView()
: CFormView(CCntEditView::IDD)
{
//{{AFX_DATA_INIT(CCntEditView)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
pDoc = NULL;
m_ptblUndo = NULL;
}
CCntEditView::~CCntEditView()
{
if (m_ptblUndo)
delete m_ptblUndo;
}
void CCntEditView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
{
if (lHint == CNT_HINT_SAVE)
UpdateData(TRUE);
else {
pDoc = GetDocument();
ContentsListBox.SubclassDlgItem(IDC_LIST_CONTENTS, this);
ContentsListBox.Initialize(&pDoc->tblContents);
UpdateData(FALSE);
}
}
void CCntEditView::DoDataExchange(CDataExchange* pDX)
{
CFormView::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CCntEditView)
// NOTE: the ClassWizard will add DDX and DDV calls here
//}}AFX_DATA_MAP
if (!pDX->m_bSaveAndValidate) { // initialization
if (pDoc) {
FillListBox();
// if (!IsDbcsSystem())
CBroadCastChildren foo(m_hWnd, WM_SETFONT,
(WPARAM) hfontSmall, FALSE);
SetTranslation();
/*
* We forcibly remove a .CNT extension since this will cause
* WinHelp to fail.
*/
if (!pDoc->cszBase.IsEmpty()) {
PSTR psz = StrChrDBCS(pDoc->cszBase, '.');
if (psz && nstrisubcmp(psz, ".CNT"))
strcpy(psz, ".HLP"); // silently force it to .HLP extension
}
DDX_Text(pDX, IDC_EDIT_HELP_TITLE, pDoc->cszTitle);
DDX_Text(pDX, IDC_EDIT_BASE_FILE, pDoc->cszBase);
}
}
else { // save the data
DDX_Text(pDX, IDC_EDIT_HELP_TITLE, pDoc->cszTitle);
DDX_Text(pDX, IDC_EDIT_BASE_FILE, pDoc->cszBase);
/*
* We forcibly remove a .CNT extension since this will cause
* WinHelp to fail.
*/
if (!pDoc->cszBase.IsEmpty()) {
PSTR psz = StrChrDBCS(pDoc->cszBase, '.');
if (psz && nstrisubcmp(psz, ".CNT"))
strcpy(psz, ".HLP"); // silently force it to .HLP extension
}
}
}
void STDCALL CCntEditView::FillListBox()
{
ASSERT(pDoc);
// Suspend drawing
::SendMessage(ContentsListBox.m_hWnd, WM_SETREDRAW, FALSE, 0);
// Chicago and NT listboxes could just set the amount of data
for (int pos = 1; pos <= pDoc->tblContents.CountStrings(); pos++)
ContentsListBox.AddString("");
// Enable drawing
::SendMessage(ContentsListBox.m_hWnd, WM_SETREDRAW, TRUE, 0);
}
LRESULT CCntEditView::OnContextMenu(WPARAM wParam, LPARAM lParam)
{
::WinHelp((HWND) wParam,
AfxGetApp()->m_pszHelpFilePath,
HELP_CONTEXTMENU, (DWORD) (LPVOID) aHelpIds);
return 0;
}
LRESULT CCntEditView::OnF1Help(WPARAM wParam, LPARAM lParam)
{
::WinHelp((HWND) ((LPHELPINFO) lParam)->hItemHandle,
AfxGetApp()->m_pszHelpFilePath,
HELP_WM_HELP, (DWORD) (LPVOID) aHelpIds);
return 0;
}
void CCntEditView::OnButtonEdit()
{
int cursel;
if ((cursel = ContentsListBox.GetCurSel()) != LB_ERR) {
CString cszCtx;
CString cszText;
CString cszHelpFile;
CString cszWindow;
// use allocated memory to save stack space
CMem line(512);
pDoc->tblContents.GetString(line.psz, cursel + 1);
PSTR psz;
if ((psz = StrChr(line.psz, WINDOWSEPARATOR, _fDBCSSystem))) {
*psz++ = '\0';
SzTrimSz(psz);
cszWindow = psz;
}
if ((psz = StrChr(line.psz, FILESEPARATOR, _fDBCSSystem))) {
*psz++ = '\0';
SzTrimSz(psz);
cszHelpFile = psz;
}
if ((psz = StrChr(line.psz, CH_EQUAL, _fDBCSSystem))) {
*psz++ = '\0';
SzTrimSz(psz);
cszCtx = psz;
}
SzTrimSz(line.psz);
cszText = line.psz;
CEditContent edit(&cszCtx, &cszText, &cszHelpFile, &cszWindow,
TRUE, this);
if (edit.DoModal() != IDOK)
return;
strcpy(line.psz, cszText);
if (!cszCtx.IsEmpty()) {
strcat(line.psz, "=");
strcat(line.psz, cszCtx);
// Don't allow file or window unless there's a context string
if (!cszHelpFile.IsEmpty()) {
strcat(line.psz, "@");
strcat(line.psz, cszHelpFile);
}
if (!cszWindow.IsEmpty()) {
strcat(line.psz, ">");
strcat(line.psz, cszWindow);
}
}
CreateUndo();
pDoc->tblContents.ReplaceString(line.psz, cursel + 1);
ContentsListBox.Invalidate();
pDoc->SetModifiedFlag(TRUE);
}
}
void CCntEditView::OnButtonIndex()
{
static const DWORD aIndexHelpIDs[] = {
IDC_LIST_INDEX, IDH_INDEX_LIST_INDEX,
IDC_BUTTON_ADD, IDH_INDEX_BUTTON_ADD,
IDC_BUTTON_REMOVE, IDH_INDEX_BUTTON_REMOVE,
IDC_BUTTON_EDIT, IDH_INDEX_BUTTON_EDIT,
0, 0
};
CDlgIndex dlgindex(pDoc->tblIndexes, CDlgIndex::INDEX,
aIndexHelpIDs, IDH_BAS_CNT_COMBINE_HLP_FILES);
if (dlgindex.DoModal() == IDOK)
pDoc->SetModifiedFlag(TRUE);
}
void CCntEditView::OnButtonInsAbove()
{
int cursel = ContentsListBox.GetCurSel();
if (cursel != LB_ERR) {
if (Insert(cursel + 1)) {
ContentsListBox.SetCurSel(cursel);
pDoc->SetModifiedFlag(TRUE);
}
return;
}
// If list box is empty, add to first entry
if (ContentsListBox.GetCount() < 1) {
if (Insert(0)) {
ContentsListBox.SetCurSel(0);
pDoc->SetModifiedFlag(TRUE);
}
}
else {
MsgBox(IDS_SELECT_FIRST);
return;
}
}
void CCntEditView::OnButtonInsBelow()
{
int cursel = ContentsListBox.GetCurSel();
if (cursel != LB_ERR) {
if (Insert(cursel + 2)) {
ContentsListBox.SetCurSel(cursel + 1);
pDoc->SetModifiedFlag(TRUE);
}
return;
}
// Nothing selected, so insert above
OnButtonInsAbove();
}
void CCntEditView::OnButtonLinks()
{
CDlgLink dlgLink(pDoc);
if (dlgLink.DoModal() == IDOK)
pDoc->SetModifiedFlag(TRUE);
}
void CCntEditView::OnButtonRemove()
{
UINT cursel;
if ((cursel = ContentsListBox.GetCurSel()) != LB_ERR) {
CreateUndo();
pDoc->tblContents.RemoveString(cursel + 1);
ContentsListBox.ResetContent();
FillListBox();
ContentsListBox.Invalidate();
pDoc->SetModifiedFlag(TRUE);
// Select something
if (cursel < (UINT) ContentsListBox.GetCount())
ContentsListBox.SetCurSel(cursel);
else if (cursel > 0)
ContentsListBox.SetCurSel(--cursel);
}
}
void CCntEditView::OnButtonTabs()
{
static const DWORD aTabHelpIDs[] = {
IDC_LIST_INDEX, IDH_LIST_TABS,
IDC_BUTTON_ADD, IDH_BTN_ADD_TABS,
IDC_BUTTON_REMOVE, IDH_BTN_REMOVE_TABS,
IDC_BUTTON_EDIT, IDH_BTN_EDIT_TABS,
0, 0
};
CDlgIndex dlgindex(pDoc->tblTabs, CDlgIndex::TAB,
aTabHelpIDs, IDH_ADD_NEW_TAB);
if (dlgindex.DoModal() == IDOK)
pDoc->SetModifiedFlag(TRUE);
}
void CCntEditView::OnDblclkListContents()
{
OnButtonEdit();
}
BOOL STDCALL CCntEditView::Insert(int pos)
{
CString cszCtx;
CString cszText;
CString cszHelpFile;
CString cszWindow;
// use allocated memory to save stack space
CMem line(512);
UINT posTmp = (pos > 0) ? pos - 1 : 0;
if (pos > 0) {
for (posTmp = pos - 1; posTmp; posTmp--) {
ConfirmOrDie(pDoc->tblContents.GetString(line.psz, posTmp));
if (isdigit(*line.psz)) {
/*
* We default to entering a topic line, which means
* we must increase the level by one if the previous
* line was a book. If the entry we get back is a book,
* then we reduce its level by one.
*/
if (!(FindEqual(line.psz)))
*line.psz += 1;
line.psz[2] = '\0';
cszText = line.psz;
break;
}
}
}
if (posTmp == 0)
cszText = "1 ";
CEditContent edit(&cszCtx, &cszText, &cszHelpFile, &cszWindow,
FALSE, this);
if (edit.DoModal() != IDOK)
return FALSE;
strcpy(line.psz, cszText);
if (!cszCtx.IsEmpty()) {
strcat(line.psz, "=");
strcat(line.psz, cszCtx);
// Don't allow file or window unless there's a context string
if (!cszHelpFile.IsEmpty()) {
strcat(line.psz, "@");
strcat(line.psz, cszHelpFile);
}
if (!cszWindow.IsEmpty()) {
strcat(line.psz, ">");
strcat(line.psz, cszWindow);
}
}
else if (isdigit(*line.psz) && *line.psz > '1')
*line.psz -= 1; // reduce the level by one if its a book
// REVIEW: if we insert a book above a topic, then we need to
// indent all the topics.
CreateUndo();
if (pos > pDoc->tblContents.CountStrings())
pDoc->tblContents.AddString(line.psz);
else
pDoc->tblContents.InsertString(line.psz, pos);
ContentsListBox.ResetContent();
FillListBox();
ContentsListBox.Invalidate();
pDoc->SetModifiedFlag(TRUE);
return TRUE;
}
void CCntEditView::OnSelchangeListContents()
{
UINT cursel;
if ((cursel = ContentsListBox.GetCurSel()) != LB_ERR) {
LPSTR psz = pDoc->tblContents.GetPointer(cursel + 1);
ASSERT(psz);
if (isdigit(*psz)) {
// REVIEW: need to determine whether to disable/enable
// Increase/Decrease level buttons.
}
}
}
void CCntEditView::OnHelp()
{
HelpOverview(m_hWnd, IDH_CONTENTS_FILE_EDITOR);
}
void CCntEditView::OnButtonMoveRight()
{
#ifdef _DEBUG
LPSTR pszItem, pszNextItem;
#endif
int cursel;
if ((cursel = ContentsListBox.GetCurSel()) != LB_ERR) {
CMem line(512);
CMem lineTmp(512);
cursel++; // since the table starts at 1
pDoc->tblContents.GetString(line.psz, cursel);
if (!isdigit(*line.psz)) {
MsgBox(IDS_CANT_CHANGE_LEV);
return;
}
if (FindEqual(line.psz)) {
/*
* It's possible that a book was inserted above a topic.
* In that case, it's probably the same level, and we may
* want to move all the topics underneath it to be
* subordinate to the book.
*/
char curlevel = *line.psz;
if (cursel > 1) {
UINT i = cursel - 1;
do {
pDoc->tblContents.GetString(line.psz, i);
if (isdigit(*line.psz))
break;
} while (--i >= 0);
if (i >= 0 && !FindEqual(line.psz) &&
curlevel <= *line.psz)
goto ShiftRight;
}
MsgBox(IDS_CANT_INCREASE_TOPIC);
return;
}
if (*line.psz >= '9') {
MsgBox(IDS_EXCEEDED_MAX_LEVEL);
return;
}
if (cursel > 1) {
pDoc->tblContents.GetString(lineTmp.psz, cursel - 1);
if (isdigit(*lineTmp.psz)) {
if (*line.psz > *lineTmp.psz ||
(*line.psz == *lineTmp.psz && FindEqual(lineTmp.psz))) {
MsgBox(IDS_CANT_SKIP_LEVELS);
return;
}
}
}
// REVIEW: if this is the first book, confirm that the user
// really wants to increase the level, and if so, increase
// all levels. Useful for when this is an :included .CNT file.
ShiftRight:
CreateUndo();
do {
#ifdef _DEBUG
pszItem = pDoc->tblContents.GetPointer(cursel);
pszNextItem = pDoc->tblContents.GetPointer(cursel + 1);
#endif
*pDoc->tblContents.GetPointer(cursel++) += 1;
if (cursel > pDoc->tblContents.CountStrings())
break;
// Ignore comments and command lines
while (!isdigit(*pDoc->tblContents.GetPointer(cursel)) &&
cursel < pDoc->tblContents.CountStrings())
cursel++;
if (!isdigit(*pDoc->tblContents.GetPointer(cursel)))
break;
/*
* loop continues while we have topics, or a book that has a
* greater level.
*/
} while (FindEqual(pDoc->tblContents.GetPointer(cursel)) ||
*pDoc->tblContents.GetPointer(cursel) > *line.psz);
ContentsListBox.Invalidate();
pDoc->SetModifiedFlag(TRUE);
}
}
void CCntEditView::OnButtonMoveLeft()
{
#ifdef _DEBUG
LPSTR pszItem, pszNextItem;
#endif
int cursel;
if ((cursel = ContentsListBox.GetCurSel()) != LB_ERR) {
char szLine[MAX_CNT_LINE];
cursel++; // since the table starts at 1
pDoc->tblContents.GetString(szLine, cursel);
if (!isdigit(*szLine)) {
MsgBox(IDS_CANT_CHANGE_LEV);
return;
}
if (*szLine < '2') {
MsgBox(IDS_EXCEEDED_MIN_LEVEL);
return;
}
if (FindEqual(szLine)) {
char szNextLine[MAX_CNT_LINE];
int pos = cursel + 1;
if (pos < pDoc->tblContents.CountStrings()) {
do {
pDoc->tblContents.GetString(szNextLine, pos++);
} while (!isdigit(szNextLine[0]) && pos <
pDoc->tblContents.CountStrings());
if (pos < pDoc->tblContents.CountStrings()) {
if (szNextLine[0] >= szLine[0]) {
if (AfxMessageBox(IDS_MOVE_TOPIC_LEFT, MB_YESNO, 0) ==
IDYES) {
szLine[0]--;
goto MoveAll;
}
}
}
}
// Just move this topic
CreateUndo();
*pDoc->tblContents.GetPointer(cursel) -= 1;
ContentsListBox.Invalidate();
pDoc->SetModifiedFlag(TRUE);
return;
}
CreateUndo();
do {
MoveAll:
#ifdef _DEBUG
pszItem = pDoc->tblContents.GetPointer(cursel);
pszNextItem = pDoc->tblContents.GetPointer(cursel + 1);
#endif
*pDoc->tblContents.GetPointer(cursel++) -= 1;
if (cursel > pDoc->tblContents.CountStrings())
break;
// Ignore comments and command lines
while (!isdigit(*pDoc->tblContents.GetPointer(cursel)) &&
cursel < pDoc->tblContents.CountStrings())
cursel++;
if (!isdigit(*pDoc->tblContents.GetPointer(cursel)))
break;
} while (*pDoc->tblContents.GetPointer(cursel) > *szLine);
ContentsListBox.Invalidate();
pDoc->SetModifiedFlag(TRUE);
}
}
void CCntEditView::OnButtonSearch()
{
#ifndef _DEBUG
szMsgBox("Not implemented yet");
#else
if (_afxLastFRState.pFindReplaceDlg != NULL) {
_afxLastFRState.pFindReplaceDlg->SetActiveWindow();
_afxLastFRState.pFindReplaceDlg->ShowWindow(SW_SHOW);
return;
}
CString strFind;
strFind = _afxLastFRState.strFind;
_afxLastFRState.pFindReplaceDlg = new CFindReplaceDialog;
DWORD dwFlags = FR_HIDEWHOLEWORD;
if (_afxLastFRState.bNext)
dwFlags |= FR_DOWN;
if (_afxLastFRState.bCase)
dwFlags |= FR_MATCHCASE;
if (!_afxLastFRState.pFindReplaceDlg->Create(TRUE, strFind,
NULL, dwFlags, this)) {
_afxLastFRState.pFindReplaceDlg = NULL;
ASSERT_VALID(this);
return;
}
ASSERT(_afxLastFRState.pFindReplaceDlg != NULL);
_afxLastFRState.bFindOnly = TRUE;
// TODO: Add your control notification handler code here
#endif // _debug
}
LRESULT CCntEditView::OnFindReplaceCmd(WPARAM, LPARAM lParam)
{
ASSERT_VALID(this);
CFindReplaceDialog* pDialog = CFindReplaceDialog::GetNotifier(lParam);
ASSERT(pDialog != NULL);
ASSERT(pDialog == _afxLastFRState.pFindReplaceDlg);
if (pDialog->IsTerminating()) {
_afxLastFRState.pFindReplaceDlg = NULL;
}
else if (pDialog->FindNext()) {
// OnFindNext(pDialog->GetFindString(),
// pDialog->SearchDown(), pDialog->MatchCase());
}
else if (pDialog->ReplaceCurrent()) {
ASSERT(!_afxLastFRState.bFindOnly);
// OnReplaceSel(pDialog->GetFindString(),
// pDialog->SearchDown(), pDialog->MatchCase(),
// pDialog->GetReplaceString());
}
else if (pDialog->ReplaceAll()) {
ASSERT(!_afxLastFRState.bFindOnly);
// OnReplaceAll(pDialog->GetFindString(), pDialog->GetReplaceString(),
// pDialog->MatchCase());
}
ASSERT_VALID(this);
return 0;
}
void CCntEditView::OnChangeEditBaseFile()
{
pDoc->SetModifiedFlag(TRUE);
}
void CCntEditView::OnChangeEditHelpTitle()
{
pDoc->SetModifiedFlag(TRUE);
}
/***************************************************************************
FUNCTION: CCntEditView::SetTranslation
PURPOSE: Enables or disables controls depending on whether
the translation flag is set
PARAMETERS:
void
RETURNS:
COMMENTS:
MODIFICATION DATES:
02-Jun-1995 [ralphw]
***************************************************************************/
void CCntEditView::SetTranslation(void)
{
((CEdit*) GetDlgItem(IDC_EDIT_BASE_FILE))->EnableWindow(!fTranslator);
((CButton*) GetDlgItem(IDC_BUTTON_REMOVE))->EnableWindow(!fTranslator);
((CButton*) GetDlgItem(IDC_BUTTON_INS_ABOVE))->EnableWindow(!fTranslator);
((CButton*) GetDlgItem(IDC_BUTTON_INS_BELOW))->EnableWindow(!fTranslator);
((CButton*) GetDlgItem(IDC_BUTTON_REDUCE_LEVEL))->EnableWindow(!fTranslator);
((CButton*) GetDlgItem(IDC_BUTTON_INCREASE_LEVEL))->EnableWindow(!fTranslator);
((CButton*) GetDlgItem(IDC_BUTTON_LINKS))->EnableWindow(!fTranslator);
}
void CCntEditView::OnTranslator()
{
fTranslator = !fTranslator;
SetTranslation();
}
void CCntEditView::OnUndo()
{
if (m_ptblUndo) {
pDoc->tblContents.Empty();
for (int i = 1; i <= m_ptblUndo->CountStrings(); i++)
pDoc->tblContents.AddString(m_ptblUndo->GetPointer(i));
delete m_ptblUndo;
m_ptblUndo = NULL;
ContentsListBox.ResetContent();
FillListBox();
}
}
void CCntEditView::OnUpdateTranslator(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck(fTranslator);
}
void CCntEditView::OnUpdateUndo(CCmdUI* pCmdUI)
{
pCmdUI->Enable((BOOL) m_ptblUndo);
}
/***************************************************************************
FUNCTION: CCntEditView::OnUpdateTranslation
PURPOSE: Enables or disabled the menu item based on whether
fTranslation is set.
PARAMETERS:
pCmdUI
RETURNS:
COMMENTS:
MODIFICATION DATES:
03-Nov-1995 [ralphw]
***************************************************************************/
void CCntEditView::OnUpdateTranslation(CCmdUI* pCmdUI)
{
pCmdUI->Enable(!fTranslator);
}
void CCntEditView::OnButtonEditFileName(void)
{
static DWORD aHelpIDs[] = {
IDH_LIST_EDIT_DEFAULT_HELP,
IDH_EDIT_DEFAULT_HELP_WINDOW,
IDH_EDIT_DEFAULT_HELP_TITLE
};
CAddAlias addalias(this, 0, aHelpIDs);
addalias.idDlgCaption = IDS_DLG_DEFAULT;
addalias.idStr1Prompt = IDS_DEF_HELP_FILENAME;
addalias.idStr2Prompt = IDS_DEF_HELP_WINDOW;
addalias.idStr3Prompt = IDS_DEF_TITLE;
addalias.cbMaxStr1 = MAX_PATH;
addalias.cbMaxStr2 = MAX_WINDOW_NAME - 1;
// Set the controls to disable if fTranslation is TRUE
addalias.m_id1_fTrackTranslation = TRUE;
addalias.m_id2_fTrackTranslation = TRUE;
char szBuf[MAX_PATH];
((CEdit*) GetDlgItem(IDC_EDIT_BASE_FILE))->
GetWindowText(szBuf, sizeof(szBuf));
PSTR psz = StrRChr(szBuf, WINDOWSEPARATOR, _fDBCSSystem);
if (!IsEmptyString(psz))
*psz++ = '\0';
addalias.m_str1 = szBuf;
addalias.m_str2 = (psz ? psz : txtZeroLength);
((CEdit*) GetDlgItem(IDC_EDIT_HELP_TITLE))->
GetWindowText(addalias.m_str3);
if (addalias.DoModal() == IDOK) {
if (!addalias.m_str2.IsEmpty()) {
strcpy(szBuf, addalias.m_str2);
SzTrimSz(szBuf);
if (*szBuf) {
addalias.m_str1 += ">"; // add window separator
addalias.m_str1 += szBuf;
}
}
((CEdit*) GetDlgItem(IDC_EDIT_BASE_FILE))->
SetWindowText(addalias.m_str1);
((CEdit*) GetDlgItem(IDC_EDIT_HELP_TITLE))->
SetWindowText(addalias.m_str3);
}
}
void CCntEditView::CreateUndo(void)
{
if (m_ptblUndo)
delete m_ptblUndo;
m_ptblUndo = new CTable;
for (int i = 1; i <= pDoc->tblContents.CountStrings(); i++)
m_ptblUndo->AddString(pDoc->tblContents.GetPointer(i));
}
/***************************************************************************
FUNCTION: FindEqual
PURPOSE: Determine if there is an unescaped equal character in the line
PARAMETERS:
pszLine
RETURNS:
COMMENTS:
MODIFICATION DATES:
07-Nov-1995 [ralphw]
***************************************************************************/
static PSTR STDCALL FindEqual(PCSTR pszLine)
{
PSTR psz = (PSTR) pszLine;
while ((psz = StrChr(psz, '=', _fDBCSSystem))) {
if (psz == pszLine)
return psz;
else if (psz[-1] == '\\') {
psz++;
continue;
}
else
return psz;
}
return NULL;
}
void CCntEditView::OnSize(UINT nType, int cx, int cy)
{
// If we're not minimized and our size is changing, move stuff
// around to fit the new window size.
if (nType != SIZE_MINIMIZED && (m_siz.cx != cx || m_siz.cy != cy)) {
// Spacing around the margins of the dialog; double these
// values for spacing between controls.
DWORD dwBaseUnits = GetDialogBaseUnits();
int dx = (3 * LOWORD(dwBaseUnits)) / 4;
int dy = (3 * HIWORD(dwBaseUnits)) / 8;
// Get the rect, relative to the dialog client area, of the
// topmost right-aligned control.
RECT rcRight;
CWnd *pCtl = GetDlgItem(IDEDIT_DIR_NAME);
if (pCtl == NULL)
goto bail;
pCtl->GetWindowRect(&rcRight);
ScreenToClient(&rcRight);
int cxButton = rcRight.right - rcRight.left;
int cyButton = rcRight.bottom - rcRight.top;
// Get the rect, relative to the dialog client area, of the
// topmost left-aligned control.
RECT rcLeft;
pCtl = GetDlgItem(IDC_STATIC_BASE_FILE);
pCtl->GetWindowRect(&rcLeft);
ScreenToClient(&rcLeft);
// Calculate the ideal x-coordinate for right-aligned buttons,
// and the resulting list-box width.
int xRight = cx - cxButton - dx;
int cxLeft = xRight - rcLeft.left - 2 * dx;
// If cxLeft is too small, move buttons to the right.
if (cxLeft < (126 * LOWORD(dwBaseUnits)) / 4) {
cxLeft = (126 * LOWORD(dwBaseUnits)) / 4;
xRight = rcLeft.left + cxLeft + 2 * dx;
}
// Calculate the width of the edit controls and their
// corresponding static controls.
int cxEdit = cxLeft / 2 - dx;
// We're going to move all 18 controls.
HDWP hdwp = BeginDeferWindowPos(18);
if (hdwp == NULL)
goto bail;
// Move and resize the two static controls.
DeferWindowPos(
hdwp, pCtl->m_hWnd, NULL,
0, 0, cxEdit, rcLeft.bottom - rcLeft.top,
SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE
);
DeferWindowPos(
hdwp, GetDlgItem(IDC_STATIC_HELP_TITLE)->m_hWnd, NULL,
xRight - cxEdit - 2 * dx, rcLeft.top,
cxEdit, rcLeft.bottom - rcLeft.top,
SWP_NOZORDER | SWP_NOACTIVATE
);
// Move and resize the two edit controls.
pCtl = GetDlgItem(IDC_EDIT_BASE_FILE);
pCtl->GetWindowRect(&rcLeft);
ScreenToClient(&rcLeft);
DeferWindowPos(
hdwp, pCtl->m_hWnd, NULL, 0, 0,
cxEdit, rcLeft.bottom - rcLeft.top,
SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE
);
DeferWindowPos(
hdwp, GetDlgItem(IDC_EDIT_HELP_TITLE)->m_hWnd, NULL,
xRight - cxEdit - 2 * dx, rcLeft.top,
cxEdit, rcLeft.bottom - rcLeft.top,
SWP_NOZORDER | SWP_NOACTIVATE
);
// Move the IDEDIT_DIR_NAME button.
DeferWindowPos(
hdwp, GetDlgItem(IDEDIT_DIR_NAME)->m_hWnd, NULL,
xRight, rcRight.top, 0, 0,
SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE
);
// Reposition the top bevel.
DeferWindowPos(
hdwp, GetDlgItem(IDC_TOP_BEVEL)->m_hWnd, NULL,
0, rcLeft.bottom, cx, cyButton,
SWP_NOZORDER | SWP_NOACTIVATE
);
// Fill in ideal list box rect (Note: .left is already
// correct and we don't care about .right).
rcLeft.top = rcLeft.bottom + cyButton;
rcLeft.bottom = cy - (dy + 2 * cyButton);
// Array of control IDs for right aligned buttons.
#define C_RBUTTONS 7
#define C_GAPS (C_RBUTTONS - 1)
#define C_ODD_GAPS ((C_RBUTTONS + 1) / 2 - 1)
static const UINT aButtonIDs[C_RBUTTONS] = {
IDC_BUTTON_EDIT,
IDC_BUTTON_REMOVE,
IDC_BUTTON_INS_ABOVE,
IDC_BUTTON_INS_BELOW,
IDC_BUTTON_INCREASE_LEVEL,
IDC_BUTTON_REDUCE_LEVEL,
IDC_BUTTON_SEARCH,
};
// Start with default button spacing and adjust to fit if necessary.
int dyGap = (3 * LOWORD(dwBaseUnits)) / 4;
int dyOddGap = 3 * dy;
int cyList = rcLeft.bottom - rcLeft.top;
if (C_RBUTTONS * cyButton + C_GAPS * dyGap + C_ODD_GAPS * dyOddGap > cyList) {
// No gaps between buttons, and grow list if necessary.
if (C_RBUTTONS * cyButton >= cyList) {
dyGap = dyOddGap = 0;
cyList = C_RBUTTONS * cyButton;
rcLeft.bottom = rcLeft.top + cyList;
}
// No odd gaps.
else if (C_RBUTTONS * cyButton + C_GAPS * dyGap >= cyList) {
dyOddGap = 0;
dyGap = (cyList - C_RBUTTONS * cyButton) / C_GAPS;
}
// Default gaps and reduced odd gaps.
else {
dyOddGap = (cyList - (C_RBUTTONS * cyButton + C_GAPS * dyGap)) / C_ODD_GAPS;
}
}
// Move all the right-aligned buttons.
rcRight.top = rcLeft.top;
UINT iCtl;
for (iCtl = 0; iCtl < C_RBUTTONS; iCtl++) {
DeferWindowPos(
hdwp, GetDlgItem(aButtonIDs[iCtl])->m_hWnd, NULL,
xRight, rcRight.top, 0, 0,
SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE
);
rcRight.top += dyGap + cyButton;
if (iCtl & 1)
rcRight.top += dyOddGap;
}
// Move and size the list box.
DeferWindowPos(
hdwp, GetDlgItem(IDC_LIST_CONTENTS)->m_hWnd, NULL,
rcLeft.left, rcLeft.top, cxLeft, cyList,
SWP_NOZORDER | SWP_NOACTIVATE
);
// Move and size the bottom bevel control.
DeferWindowPos(
hdwp, GetDlgItem(IDC_BOTTOM_BEVEL)->m_hWnd, NULL,
0, rcLeft.bottom, cx, cyButton,
SWP_NOZORDER | SWP_NOACTIVATE
);
// Move the three bottom buttons.
static const UINT aBottomIDs[] = {
IDC_BUTTON_INDEX,
IDC_BUTTON_LINKS,
IDC_BUTTON_TABS
};
int xBtn = cx - dx; // right side of first button
for (iCtl = 0; iCtl < 3; iCtl++) {
pCtl = GetDlgItem(aBottomIDs[iCtl]);
pCtl->GetWindowRect(&rcRight);
xBtn -= (rcRight.right - rcRight.left); // left side
DeferWindowPos(
hdwp, pCtl->m_hWnd, NULL,
xBtn, rcLeft.bottom + cyButton, 0, 0,
SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE
);
xBtn -= 2 * dx; // add in spacing
}
EndDeferWindowPos(hdwp);
SetScrollSizes(MM_TEXT, CSize(cx, cy));
}
bail:
CFormView::OnSize(nType, cx, cy);
}