2025-11-27 16:46:48 +09:00

507 lines
16 KiB
C++

// LeftView.cpp : implementation of the CLeftView class
//
#include "stdafx.h"
#include "ParserView.h"
#include "ParserViewDoc.h"
#include "LeftView.h"
#include "UTBStrOp.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CLeftView
IMPLEMENT_DYNCREATE(CLeftView, CTreeView)
BEGIN_MESSAGE_MAP(CLeftView, CTreeView)
//{{AFX_MSG_MAP(CLeftView)
ON_NOTIFY_REFLECT(TVN_ITEMEXPANDING, OnItemExpanding)
ON_NOTIFY_REFLECT(TVN_SELCHANGED, OnSelChanged)
ON_COMMAND(ID_EXPAND_ALL, OnExpandAll)
ON_COMMAND(ID_COLLAPSE_ALL, OnCollapseAll)
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CTreeView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CTreeView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CTreeView::OnFilePrintPreview)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CLeftView construction/destruction
CLeftView::CLeftView()
{
m_nCloseEmptyFolder = 0;
m_nCloseFolder = 1;
m_nOpenFolder = 2;
m_nTextItem = 3;
m_nAttribute = 4;
m_nComment = 5;
m_nProcInstr = 6;
m_nMarkup = 7;
m_nCData = 8;
m_pRightView = NULL;
}
CLeftView::~CLeftView()
{
}
BOOL CLeftView::PreCreateWindow(CREATESTRUCT& cs)
{
cs.style |= (TVS_HASBUTTONS|TVS_HASLINES|TVS_LINESATROOT|TVS_FULLROWSELECT);
return CTreeView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CLeftView drawing
void CLeftView::OnDraw(CDC* /*pDC*/)
{
}
/////////////////////////////////////////////////////////////////////////////
// CLeftView printing
BOOL CLeftView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CLeftView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
void CLeftView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
// Returns a string that is less than or equal to 20 chars long
LPCTSTR CLeftView::BriefText(LPCTSTR szText)
{
#define BRIEF_LENGTH 20
static TCHAR szBrief[BRIEF_LENGTH+1];
if (_tcslen(szText) <= BRIEF_LENGTH)
return szText;
UTBStr::tcsncpy(szBrief, 20, szText, BRIEF_LENGTH-3);
szBrief[BRIEF_LENGTH-3] = TEXT('\0');
UTBStr::tcscat(szBrief, BRIEF_LENGTH, TEXT("..."));
return szBrief;
}
// Fills the tree recursively with the contents of the parser tree
void CLeftView::FillTree(HTREEITEM hParent, COXParserElement* pElement)
{
if (pElement->GetType() != COXParserObject::ELEMENT)
return;
int i = 0;
for (i = 0; i < pElement->NumAttributes(); i++)
{
COXAttribute* pAttribute = pElement->Attribute(i);
if (!pAttribute) continue;
TCHAR szText[1024];
if (pAttribute->GetAttributeType() == COXAttribute::ATTR_STRING)
UTBStr::stprintf(szText, 1024, TEXT("\"%s\"=\"%s\""), pAttribute->GetName(), pAttribute->GetStringValue());
else if (pAttribute->GetAttributeType() == COXAttribute::ATTR_INTEGER)
UTBStr::stprintf(szText, 1024, TEXT("\"%s\"=%d"), pAttribute->GetName(), pAttribute->GetIntValue());
HTREEITEM hItem = GetTreeCtrl().InsertItem(szText, m_nAttribute, m_nAttribute, hParent);
GetTreeCtrl().SetItemData(hItem, (DWORD) pAttribute);
}
for (i = 0; i < pElement->NumObjects(); i++)
{
COXParserObject* pObject = pElement->Object(i);
if (!pObject) continue;
HTREEITEM hNewParent;
switch (pObject->GetType())
{
case COXParserObject::CDATA:
hNewParent = GetTreeCtrl().InsertItem(BriefText(pObject->GetText()),
m_nCData, m_nCData,
hParent);
GetTreeCtrl().SetItemData(hNewParent, (DWORD) pObject);
break;
case COXParserObject::COMMENT:
hNewParent = GetTreeCtrl().InsertItem(BriefText(pObject->GetText()),
m_nComment, m_nComment,
hParent);
GetTreeCtrl().SetItemData(hNewParent, (DWORD) pObject);
break;
case COXParserObject::ELEMENT:
if (!((COXParserElement*)pObject)->NumObjects())
hNewParent = GetTreeCtrl().InsertItem(pObject->GetText(),
m_nCloseEmptyFolder, m_nCloseEmptyFolder,
hParent);
else
hNewParent = GetTreeCtrl().InsertItem(pObject->GetText(),
m_nCloseFolder, m_nCloseFolder,
hParent);
GetTreeCtrl().SetItemData(hNewParent, (DWORD) pObject);
FillTree(hNewParent, (COXParserElement*)pObject);
break;
case COXParserObject::MARKUP:
hNewParent = GetTreeCtrl().InsertItem(BriefText(pObject->GetText()),
m_nMarkup, m_nMarkup,
hParent);
GetTreeCtrl().SetItemData(hNewParent, (DWORD) pObject);
break;
case COXParserObject::PLAINTEXT:
hNewParent = GetTreeCtrl().InsertItem(BriefText(pObject->GetText()),
m_nTextItem, m_nTextItem,
hParent);
GetTreeCtrl().SetItemData(hNewParent, (DWORD) pObject);
break;
case COXParserObject::PROCINSTR:
hNewParent = GetTreeCtrl().InsertItem(BriefText(pObject->GetText()),
m_nProcInstr, m_nProcInstr,
hParent);
GetTreeCtrl().SetItemData(hNewParent, (DWORD) pObject);
break;
}
}
}
void CLeftView::OnInitialUpdate()
{
CTreeView::OnInitialUpdate();
m_Images.Create(IDB_BITMAP, 16, 1, RGB(255,255,255));
GetTreeCtrl().SetImageList(&m_Images, TVSIL_NORMAL);
if (m_pRightView)
m_pRightView->GetListCtrl()->SetImageList(&m_Images, LVSIL_SMALL);
CParserViewDoc* pDoc = GetDocument();
COXParser* pParser = pDoc->GetParser();
HTREEITEM hItem = GetTreeCtrl().InsertItem(pParser->Root()->GetName(),
m_nCloseFolder, m_nCloseFolder);
GetTreeCtrl().SetItemData(hItem, (DWORD) pParser->Root());
CWaitCursor wait;
FillTree(hItem, pParser->Root());
}
/////////////////////////////////////////////////////////////////////////////
// CLeftView diagnostics
#ifdef _DEBUG
void CLeftView::AssertValid() const
{
CTreeView::AssertValid();
}
void CLeftView::Dump(CDumpContext& dc) const
{
CTreeView::Dump(dc);
}
CParserViewDoc* CLeftView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CParserViewDoc)));
return (CParserViewDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CLeftView message handlers
void CLeftView::OnItemExpanding(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
HTREEITEM hItem = pNMTreeView->itemNew.hItem;
COXParserObject* pObject = (COXParserObject*) GetTreeCtrl().GetItemData(hItem);
if (!pObject)
return;
if (pObject->GetType() == COXParserObject::ELEMENT)
{
COXParserElement* pElement = (COXParserElement*) pObject;
if (pNMTreeView->action == TVE_COLLAPSE)
{
if (pElement->NumObjects())
GetTreeCtrl().SetItemImage(hItem, m_nCloseFolder, m_nCloseFolder);
else
GetTreeCtrl().SetItemImage(hItem, m_nCloseEmptyFolder, m_nCloseEmptyFolder);
}
else if (pNMTreeView -> action == TVE_EXPAND)
GetTreeCtrl().SetItemImage(hItem, m_nOpenFolder, m_nOpenFolder);
}
*pResult = 0;
}
void CLeftView::OnSelChanged(NMHDR* pNMHDR, LRESULT* pResult)
{
if (!m_pRightView || !m_pRightView->GetEditView() || !m_pRightView->GetListView())
return;
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
HTREEITEM hItem = pNMTreeView->itemNew.hItem;
COXParserObject* pObject = (COXParserObject*) GetTreeCtrl().GetItemData(hItem);
if (!pObject)
return;
////////////////////////////////////////////////////////////////////////
// Fill in edit control
////////////////////////////////////////////////////////////////////////
CString strType;
int nNumObjects = 0;
int nNumAttributes = 0;
switch (pObject->GetType())
{
case COXParserObject::ATTRIBUTE:
strType = "Attribute";
break;
case COXParserObject::CDATA:
strType = "Character Data";
break;
case COXParserObject::COMMENT:
strType = "Comment";
break;
case COXParserObject::MARKUP:
strType = "Markup";
break;
case COXParserObject::PLAINTEXT:
strType = "Plain text";
break;
case COXParserObject::PROCINSTR:
strType = "Processing Instruction";
break;
case COXParserObject::ELEMENT:
strType = "Element";
nNumObjects = ((COXParserElement*)pObject)->NumObjects();
nNumAttributes = ((COXParserElement*)pObject)->NumAttributes();
break;
default:
strType = "Unknown";
break;
}
// Need to convert \n's to \r\n's
LPCTSTR szValue = pObject->GetText();
COXQuickString strNew;
strNew.SetLength(_tcslen(szValue)+1);
while (*szValue)
{
if (*szValue == TEXT('\n'))
strNew.Append(TEXT('\r'));
strNew.Append(*szValue);
szValue++;
}
CString str;
str.Format(_T("Object Type:\t%s\r\n")
_T("Attributes:\t%d\r\n")
_T("SubObjects:\t%d\r\n")
_T("Flags:\t\t%d\r\n")
_T("Name/Text:\r\n%s"),
strType, nNumAttributes, nNumObjects,
pObject->GetFlags(), (LPCTSTR)strNew);
if (pObject->GetType() == COXParserObject::ATTRIBUTE)
{
COXAttribute* pAttr = (COXAttribute*) pObject;
CString tmp;
if ( pAttr->GetAttributeType() == COXAttribute::ATTR_STRING)
tmp.Format(_T("Value:\t\t\"%s\"\r\n"), pAttr->GetStringValue());
else
tmp.Format(_T("Value:\t\t%d\r\n"), pAttr->GetIntValue());
str += tmp;
}
m_pRightView->GetEditView()->SetWindowText(str);
////////////////////////////////////////////////////////////////////////
// Fill in list control
////////////////////////////////////////////////////////////////////////
CListCtrl *pList = m_pRightView->GetListCtrl();
m_pRightView->SetRedraw(FALSE);
pList->DeleteAllItems();
if (pList->GetHeaderCtrl())
{
for (int i = pList->GetHeaderCtrl()->GetItemCount()-1; i >= 0; i--)
m_pRightView->GetListCtrl()->DeleteColumn(i);
}
if (pObject->GetType() == COXParserObject::ELEMENT)
{
pList->InsertColumn(0, _T("Object type"));
pList->InsertColumn(1, _T("Name"));
pList->InsertColumn(2, _T("SubObjects"));
pList->InsertColumn(3, _T("Value/Text"));
COXParserElement* pElement = (COXParserElement*) pObject;
int nRow = 0;
int i = 0;
for (i = 0; i < pElement->NumAttributes(); i++)
{
COXAttribute* pAttribute = pElement->Attribute(i);
if (!pAttribute) continue;
pList->InsertItem(LVIF_TEXT|LVIF_IMAGE, nRow, _T("Attribute"), 0,0, m_nAttribute, 0);
pList->SetItemText(nRow, 1, pAttribute->GetName());
pList->SetItemText(nRow, 2, _T("0"));
pList->SetItemText(nRow, 3, pAttribute->GetStringValue());
nRow++;
}
for (i = 0; i < pElement->NumObjects(); i++)
{
COXParserObject* pSubObject = pElement->Object(i);
if (!pSubObject) continue;
switch (pSubObject->GetType())
{
case COXParserObject::CDATA:
pList->InsertItem(LVIF_TEXT|LVIF_IMAGE, nRow, _T("CDATA"), 0,0, m_nCData, 0);
pList->SetItemText(nRow, 1, _T(""));
pList->SetItemText(nRow, 2, _T("0"));
pList->SetItemText(nRow, 3, pSubObject->GetText());
nRow++;
break;
case COXParserObject::PLAINTEXT:
pList->InsertItem(LVIF_TEXT|LVIF_IMAGE, nRow, _T("Plain Text"), 0,0, m_nTextItem, 0);
pList->SetItemText(nRow, 1, _T(""));
pList->SetItemText(nRow, 2, _T("0"));
pList->SetItemText(nRow, 3, pSubObject->GetText());
nRow++;
break;
case COXParserObject::COMMENT:
pList->InsertItem(LVIF_TEXT|LVIF_IMAGE, nRow, _T("Comment"), 0,0, m_nComment, 0);
pList->SetItemText(nRow, 1, _T(""));
pList->SetItemText(nRow, 2, _T("0"));
pList->SetItemText(nRow, 3, pSubObject->GetText());
nRow++;
break;
case COXParserObject::MARKUP:
pList->InsertItem(LVIF_TEXT|LVIF_IMAGE, nRow, _T("Markup"), 0,0, m_nMarkup, 0);
pList->SetItemText(nRow, 1, _T(""));
pList->SetItemText(nRow, 2, _T("0"));
pList->SetItemText(nRow, 3, pSubObject->GetText());
nRow++;
break;
case COXParserObject::PROCINSTR:
pList->InsertItem(LVIF_TEXT|LVIF_IMAGE, nRow, _T("Processing Instruction"), 0,0, m_nProcInstr, 0);
pList->SetItemText(nRow, 1, _T(""));
pList->SetItemText(nRow, 2, _T("0"));
pList->SetItemText(nRow, 3, pSubObject->GetText());
nRow++;
break;
case COXParserObject::ELEMENT:
{
COXParserElement* pSubElement = (COXParserElement*) pSubObject;
if (pSubElement->NumObjects())
pList->InsertItem(LVIF_TEXT|LVIF_IMAGE, nRow, _T("Element"),
0,0, m_nCloseFolder, 0);
else
pList->InsertItem(LVIF_TEXT|LVIF_IMAGE, nRow, _T("Element"),
0,0, m_nCloseEmptyFolder, 0);
CString strNum;
strNum.Format(_T("%d"), pSubElement->NumObjects());
pList->SetItemText(nRow, 1, pSubElement->GetName());
pList->SetItemText(nRow, 2, strNum);
pList->SetItemText(nRow, 3, _T(""));
nRow++;
}
break;
}
}
for (int col = 0; col < 3; col++)
{
pList->SetColumnWidth(col, LVSCW_AUTOSIZE);
int wc1 = pList->GetColumnWidth(col);
pList->SetColumnWidth(col,LVSCW_AUTOSIZE_USEHEADER);
int wc2 = pList->GetColumnWidth(col);
int wc = max(20, max(wc1,wc2));
pList->SetColumnWidth(col, wc);
}
pList->SetColumnWidth(3, LVSCW_AUTOSIZE_USEHEADER);
}
m_pRightView->SetRedraw(TRUE);
m_pRightView->Invalidate();
*pResult = 0;
}
void CLeftView::OnExpandAll()
{
GetTreeCtrl().SetRedraw(FALSE);
ExpandBranch(GetTreeCtrl().GetRootItem(), TVE_EXPAND);
GetTreeCtrl().SetRedraw(TRUE);
}
void CLeftView::OnCollapseAll()
{
GetTreeCtrl().SetRedraw(FALSE);
ExpandBranch(GetTreeCtrl().GetRootItem(), TVE_COLLAPSE);
GetTreeCtrl().SetRedraw(TRUE);
}
void CLeftView::ExpandBranch(HTREEITEM hItem, UINT nCode)
{
GetTreeCtrl().Expand(hItem, nCode);
HTREEITEM hChild = GetTreeCtrl().GetChildItem(hItem);
while (hChild)
{
ExpandBranch(hChild, nCode);
hChild = GetTreeCtrl().GetNextSiblingItem(hChild);
}
}