507 lines
16 KiB
C++
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);
|
|
}
|
|
}
|
|
|