// LeftView.cpp : implementation of the CLeftView class
//
#include "stdafx.h"
#include "grammarIDE.h"
#include "MainFrm.h"
#include "DlgProperties.h"
#include "grammarIDEDoc.h"
#include "grammarIDEView.h"
#include "LeftView.h"
#define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
#define GET_Y_LPARAM(lp) ((int)(short)HIWORD(lp))
#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_SELCHANGED, OnSelChanged)
ON_NOTIFY_REFLECT(NM_RCLICK, OnContextMenu)
ON_WM_INITMENUPOPUP()
ON_UPDATE_COMMAND_UI(ID_LTRCONTEXT_COLLAPSE, OnUpdateLtrcontextCollapseItem)
ON_UPDATE_COMMAND_UI(ID_LTRCONTEXT_EXPAND, OnUpdateLtrcontextExpandItem)
ON_COMMAND(ID_LTRCONTEXT_COLLAPSE, OnLtrcontextCollapseItem)
ON_COMMAND(ID_LTRCONTEXT_EXPAND, OnLtrcontextExpandItem)
ON_COMMAND(ID_LTRCONTEXT_SHOWPROPERTIES, OnLtrcontextShowProps)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CLeftView construction/destruction
CLeftView::CLeftView()
{
// TODO: add construction code here
}
CLeftView::~CLeftView()
{
}
BOOL CLeftView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CTreeView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CLeftView operations
void CLeftView::FillTree()
{
CTreeCtrl& treeCtrl = GetTreeCtrl();
const cxtPackage& pkg = *GetDocument()->m_pPkg;
const cxAnalyzerTypeMap& atm = *pkg.patmGetAnalyzerMap();
std::map<int,HTREEITEM> mapAtmToTree;
HTREEITEM hTokens = NULL;
HTREEITEM hSeperators = NULL;
HTREEITEM hRules = NULL;
HTREEITEM hGrammar = NULL;
// Set the right styles & init tree ctl
treeCtrl.DeleteAllItems();
treeCtrl.ModifyStyle( 0, TVS_FULLROWSELECT | TVS_HASBUTTONS | TVS_SHOWSELALWAYS | TVS_HASLINES | TVS_LINESATROOT );
hTokens =treeCtrl.InsertItem(_T("[tokens]"));
hSeperators =treeCtrl.InsertItem(_T("[seperators]"));
hRules =treeCtrl.InsertItem(_T("[rules]"));
hGrammar =treeCtrl.InsertItem(_T("[grammar]"));
// 1st.: Insert the 'base' elements into the tree
for(int i=1;;i++)
{
HTREEITEM hParent = NULL;
std::tstring str;
int nIDValue;
const cxAnalyzerTypeInfo *patiCur = atm.patiGetTypeInfo(i);
const cxTokenizerTokenRule *pttrCur =NULL;
if(patiCur==NULL)
break;
switch(patiCur->nGetMType())
{
case ATM_MTYPE_TOKEN:
nIDValue = atm.nGetCustIDFor(i);
pttrCur = pkg.pxtmGetTokenizerMap()->pttrGetRuleForID(nIDValue);
ASSERT(pttrCur!=NULL);
if(pttrCur->fIsFlagSet(ttrf_intermediate))
hParent = hSeperators;
else
hParent = hTokens;
break;
case ATM_MTYPE_COMP_TOKEN:
hParent = hRules;
nIDValue = atm.nGetCustIDFor(i);
pttrCur = pkg.pxtmGetTokenizerMap()->pttrGetRuleForID(nIDValue);
break;
case ATM_MTYPE_RULE:
hParent = hGrammar;
break;
default:
ASSERT(FALSE);
break;
}
str = atm.strGetStringForID(i);
HTREEITEM hTemp = treeCtrl.InsertItem(str.c_str(),hParent);
treeCtrl.SetItemData(hTemp,i);
mapAtmToTree.insert( std::make_pair(i, hTemp) );
}
// 2nd.: Insert the grammar items
const cxAnalyzerMain::ae_vec_type& vecExpr = pkg.pamGetParser()->paevecGetExpressionsVector();
cxAnalyzerMain::ae_vec_type::const_iterator it;
for(it=vecExpr.begin();it!=vecExpr.end();it++)
{
const cxAnalyzerExpression *paeCur = (*it);
std::map<int,HTREEITEM>::const_iterator iit;
const std::tstring* pstrTemp = NULL;
ASSERT(paeCur!=NULL);
iit =mapAtmToTree.find(paeCur->nGetAtmType());
ASSERT(iit!=mapAtmToTree.end());
pstrTemp=paeCur->pstrGetInitString();
ASSERT(pstrTemp!=NULL);
HTREEITEM hTemp = treeCtrl.InsertItem(pstrTemp->c_str(), iit->second);
treeCtrl.SetItemData(hTemp, paeCur->nGetIDValue());
}
}
/////////////////////////////////////////////////////////////////////////////
// CLeftView drawing
void CLeftView::OnDraw(CDC* pDC)
{
CGrammarIDEDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
}
void CLeftView::OnInitialUpdate()
{
CTreeView::OnInitialUpdate();
// TODO: You may populate your TreeView with items by directly accessing
// its tree control through a call to GetTreeCtrl().
FillTree();
}
/////////////////////////////////////////////////////////////////////////////
// CLeftView diagnostics
#ifdef _DEBUG
void CLeftView::AssertValid() const
{
CTreeView::AssertValid();
}
void CLeftView::Dump(CDumpContext& dc) const
{
CTreeView::Dump(dc);
}
CGrammarIDEDoc* CLeftView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CGrammarIDEDoc)));
return (CGrammarIDEDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CLeftView message handlers
void CLeftView::OnSelChanged(NMHDR* pNMHDR, LRESULT* pResult)
{
// TODO: Add your control notification handler code here
CMainFrame *pMainFrm = (CMainFrame*)GetParentFrame();
ASSERT( pMainFrm->IsKindOf(RUNTIME_CLASS(CMainFrame)) );
pMainFrm->GetRightPane()->ShowEditor();
*pResult = 0;
}
void CLeftView::OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint)
{
// TODO: Add your specialized code here and/or call the base class
if(pSender!=this)
{
FillTree();
}
}
void CLeftView::OnContextMenu(NMHDR* pNMHDR, LRESULT* pResult)
{
DWORD dwPos = GetMessagePos();
POINT point = { GET_X_LPARAM(dwPos), GET_Y_LPARAM(dwPos) };
CMenu menuCtx, *pMenu;
menuCtx.LoadMenu(IDR_CONTEXT);
pMenu =menuCtx.GetSubMenu(0);
//MapWindowPoints(NULL,&point,1);
UINT nCmd = pMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RETURNCMD,point.x,point.y,this);
OnCommand(nCmd,0);
*pResult = 0;
}
void CLeftView::OnInitMenuPopup(CMenu* pMenu, UINT nIndex, BOOL bSysMenu)
{
if (bSysMenu)
return; // don't support system menu
ASSERT(pMenu != NULL);
// check the enabled state of various menu items
CCmdUI state;
state.m_pMenu = pMenu;
ASSERT(state.m_pOther == NULL);
ASSERT(state.m_pParentMenu == NULL);
// determine if menu is popup in top-level menu and set m_pOther to
// it if so (m_pParentMenu == NULL indicates that it is secondary popup)
HMENU hParentMenu;
if (AfxGetThreadState()->m_hTrackingMenu == pMenu->m_hMenu)
state.m_pParentMenu = pMenu; // parent == child for tracking popup
else if ((hParentMenu = ::GetMenu(m_hWnd)) != NULL)
{
CWnd* pParent = GetTopLevelParent();
// child windows don't have menus -- need to go to the top!
if (pParent != NULL &&
(hParentMenu = ::GetMenu(pParent->m_hWnd)) != NULL)
{
int nIndexMax = ::GetMenuItemCount(hParentMenu);
for (int nIndex = 0; nIndex < nIndexMax; nIndex++)
{
if (::GetSubMenu(hParentMenu, nIndex) == pMenu->m_hMenu)
{
// when popup is found, m_pParentMenu is containing menu
state.m_pParentMenu = CMenu::FromHandle(hParentMenu);
break;
}
}
}
}
state.m_nIndexMax = pMenu->GetMenuItemCount();
for (state.m_nIndex = 0; state.m_nIndex < state.m_nIndexMax;
state.m_nIndex++)
{
state.m_nID = pMenu->GetMenuItemID(state.m_nIndex);
if (state.m_nID == 0)
continue; // menu separator or invalid cmd - ignore it
ASSERT(state.m_pOther == NULL);
ASSERT(state.m_pMenu != NULL);
if (state.m_nID == (UINT)-1)
{
// possibly a popup menu, route to first item of that popup
state.m_pSubMenu = pMenu->GetSubMenu(state.m_nIndex);
if (state.m_pSubMenu == NULL ||
(state.m_nID = state.m_pSubMenu->GetMenuItemID(0)) == 0 ||
state.m_nID == (UINT)-1)
{
continue; // first item of popup can't be routed to
}
state.DoUpdate(this, FALSE); // popups are never auto disabled
}
else
{
// normal menu item
// Auto enable/disable if frame window has 'm_bAutoMenuEnable'
// set and command is _not_ a system command.
state.m_pSubMenu = NULL;
state.DoUpdate(this, TRUE && state.m_nID < 0xF000);
}
// adjust for menu deletions and additions
UINT nCount = pMenu->GetMenuItemCount();
if (nCount < state.m_nIndexMax)
{
state.m_nIndex -= (state.m_nIndexMax - nCount);
while (state.m_nIndex < nCount &&
pMenu->GetMenuItemID(state.m_nIndex) == state.m_nID)
{
state.m_nIndex++;
}
}
state.m_nIndexMax = nCount;
}
}
void CLeftView::OnUpdateLtrcontextCollapseItem(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
CTreeCtrl& treeCtrl = GetTreeCtrl();
HTREEITEM hItem = treeCtrl.GetDropHilightItem();
if(hItem==NULL) hItem = treeCtrl.GetSelectedItem();
if( hItem!=NULL &&
treeCtrl.ItemHasChildren(hItem)!=NULL)
{
bool fExp = 0!=(treeCtrl.GetItemState(hItem,TVIS_EXPANDED)&TVIS_EXPANDED);
pCmdUI->Enable(fExp );
}
else
pCmdUI->Enable(FALSE);
}
void CLeftView::OnUpdateLtrcontextExpandItem(CCmdUI* pCmdUI)
{
// TODO: Add your command update UI handler code here
CTreeCtrl& treeCtrl = GetTreeCtrl();
HTREEITEM hItem = treeCtrl.GetDropHilightItem();
if(hItem==NULL) hItem = treeCtrl.GetSelectedItem();
if( hItem!=NULL &&
treeCtrl.GetChildItem(hItem)!=NULL)
{
bool fExp = 0!=(treeCtrl.GetItemState(hItem,TVIS_EXPANDED)&TVIS_EXPANDED);
pCmdUI->Enable(!fExp);
}
else
pCmdUI->Enable(FALSE);
}
void CLeftView::OnLtrcontextCollapseItem()
{
CTreeCtrl& treeCtrl = GetTreeCtrl();
HTREEITEM hItem = treeCtrl.GetDropHilightItem();
if(hItem==NULL) hItem = treeCtrl.GetSelectedItem();
if(hItem!=NULL)
{
treeCtrl.SetItemState(hItem,0,TVIS_EXPANDED);
Invalidate(TRUE);
}
}
void CLeftView::OnLtrcontextExpandItem()
{
CTreeCtrl& treeCtrl = GetTreeCtrl();
HTREEITEM hItem = treeCtrl.GetDropHilightItem();
if(hItem==NULL) hItem = treeCtrl.GetSelectedItem();
if(hItem!=NULL)
{
treeCtrl.SetItemState(hItem,TVIS_EXPANDED,TVIS_EXPANDED);
Invalidate(TRUE);
}
}
void CLeftView::OnLtrcontextShowProps()
{
CTreeCtrl& treeCtrl = GetTreeCtrl();
HTREEITEM hItem = treeCtrl.GetDropHilightItem();
if(hItem==NULL) hItem = treeCtrl.GetSelectedItem();
if(hItem!=NULL)
{
int nAtmType = treeCtrl.GetItemData(hItem);
CDlgProperties dlg(GetDocument()->m_pPkg,nAtmType);
dlg.DoModal();
}
}