// grammarIDEDoc.cpp : implementation of the CGrammarIDEDoc class
//
#include "stdafx.h"
#include "grammarIDE.h"
#include "grammarIDEDoc.h"
#include "ltrItemTreeWnd.h"
#include "DlgEvaluate.h"
#include <fstream>
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CGrammarIDEDoc
IMPLEMENT_DYNCREATE(CGrammarIDEDoc, CDocument)
BEGIN_MESSAGE_MAP(CGrammarIDEDoc, CDocument)
//{{AFX_MSG_MAP(CGrammarIDEDoc)
ON_UPDATE_COMMAND_UI(ID_FILE_SAVE, OnUpdateFileSave)
ON_COMMAND(ID_PARSE_REPARSE, OnParseReparse)
ON_COMMAND(ID_EDIT_RENUMBER_IDS, OnEditRenumberIds)
ON_COMMAND(ID_EDIT_RENUMBER_IDS_STRICT, OnEditRenumberIdsStrict)
//}}AFX_MSG_MAP
ON_COMMAND(ID_VIEW_EVALUATION, OnViewEvaluation)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CGrammarIDEDoc construction/destruction
CGrammarIDEDoc::CGrammarIDEDoc()
{
std::tstringstream strm("");
m_pPkg = new cxtPackage(strm);
}
CGrammarIDEDoc::~CGrammarIDEDoc()
{
delete m_pPkg;
}
BOOL CGrammarIDEDoc::OnNewDocument()
{
if (!CDocument::OnNewDocument())
return FALSE;
// TODO: add reinitialization code here
// (SDI documents will reuse this document)
delete m_pPkg;
std::tstringstream strm("");
m_pPkg = new cxtPackage(strm);
m_aRules.RemoveAll();
docElement d;
d.fSkip=false;
d.strError="";
d.strLine="[tokens]";
m_aRules.Add(d);
d.strLine="[seperators]";
m_aRules.Add(d);
d.strLine="[rules]";
m_aRules.Add(d);
d.strLine="[grammar]";
m_aRules.Add(d);
UpdateAllViews(NULL, HINT_CLEARPROPERTIES);
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CGrammarIDEDoc serialization
void CGrammarIDEDoc::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
// TODO: add storing code here
}
else
{
// TODO: add loading code here
}
}
bool CGrammarIDEDoc::TryReloadPackage(CString& strErrorText, CString& strErrorDesc)
{
std::tstringstream strm;
int i, nSize = m_aRules.GetSize();
delete m_pPkg; m_pPkg = NULL;
for(i=0; i<nSize; i++)
{
if(!m_aRules[i].fSkip)
strm << (LPCTSTR)m_aRules[i].strLine << std::endl;
}
try {
m_pPkg = new cxtPackage(strm);
}
catch(ctkExceptionBase& e)
{
std::tstringstream strm("");
CString strErr;
strErr = LookupError(e.Error())->lpszDesc;
delete m_pPkg;
m_pPkg = new cxtPackage(strm);
strErrorText = e.ErrorString();
strErrorDesc = strErr;
return false;
}
return true;
}
bool CGrammarIDEDoc::ReloadPackage(CString& strErrors)
{
bool fErrors = false;
int nCount = 0;
for(nCount=0;nCount<100;nCount++)
{
CString strErrorText, strErr;
if(TryReloadPackage(strErrorText, strErr))
break;
int i;
bool fFound = false;
for(i=0;i<m_aRules.GetSize();i++)
{
int len = strErrorText.GetLength();
CString strCmp = m_aRules[i].strLine.Right(len);
if(strCmp==strErrorText)
{
CString strTemp;
strTemp.Format("Error '%s' in line %d:\r\n'%s'\r\n\r\n", (LPCTSTR)strErr, i+1, m_aRules[i].strLine );
strErrors += strTemp;
m_aRules[i].fSkip = true;
m_aRules[i].strError = strTemp;
fErrors = true;
fFound = true;
break;
}
}
}
return fErrors;
}
bool CGrammarIDEDoc::ReloadFromEditor(CRichEditCtrl *pCtrl, CString& strErrors)
{
CHARRANGE cr;
int nPos = pCtrl->GetFirstVisibleLine();
pCtrl->GetSel(cr);
pCtrl->LockWindowUpdate();
int i, lines = pCtrl->GetLineCount();
TCHAR szBuffer[512];
szBuffer[511]='\0';
m_aRules.RemoveAll();
for(i=0;i<lines;i++)
{
pCtrl->GetLine(i,szBuffer,511);
if(szBuffer[0]!='\0' && szBuffer[1]!='\0')
{
// RichEdit
int len = _tcslen(szBuffer);
if(szBuffer[len-2]=='\r' && szBuffer[len-1]=='\n')
szBuffer[len-2]=0;
}
if(szBuffer[0]!='\0')
{
// RichEdit20a
int len = _tcslen(szBuffer);
if(szBuffer[len-1]=='\r')
szBuffer[len-1]=0;
}
if(!(i==(lines-1) && szBuffer[0]=='\0'))
{
docElement docEl;
docEl.fSkip = false;
docEl.strError = "";
docEl.strLine = szBuffer;
m_aRules.Add(docEl);
}
}
ReloadPackage(strErrors);
UpdateAllViews(NULL);
lines = m_aRules.GetSize();
for(i=0;i<lines;i++)
{
docElement& docEl = m_aRules[i];
if(docEl.fSkip)
{
CHARRANGE cr;
CHARFORMAT cf;
ZeroMemory(&cf,sizeof(cf));
cf.cbSize = sizeof(cf);
cf.dwMask = CFM_COLOR | CFM_UNDERLINE;
cf.dwEffects = CFE_UNDERLINE;
cf.crTextColor = RGB(255,0,0);
int nStart = pCtrl->LineIndex(i), nEnd = pCtrl->LineIndex(i+1);
pCtrl->GetSel(cr);
pCtrl->SetSel(nStart,nEnd);
pCtrl->SetSelectionCharFormat(cf);
pCtrl->SetSel(cr);
}
}
pCtrl->SetSel(cr);
int nPosNow = pCtrl->GetFirstVisibleLine();
pCtrl->LineScroll(-nPosNow);
pCtrl->LineScroll(nPos);
pCtrl->UnlockWindowUpdate();
// int nPos = pCtrl->GetScrollPos(SB_VERT);
return true;
}
/////////////////////////////////////////////////////////////////////////////
// CGrammarIDEDoc diagnostics
#ifdef _DEBUG
void CGrammarIDEDoc::AssertValid() const
{
CDocument::AssertValid();
}
void CGrammarIDEDoc::Dump(CDumpContext& dc) const
{
CDocument::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CGrammarIDEDoc commands
void CGrammarIDEDoc::OnViewEvaluation()
{
CDlgEvaluate dlg(*m_pPkg);
dlg.DoModal();
}
BOOL CGrammarIDEDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
if (!CDocument::OnOpenDocument(lpszPathName))
return FALSE;
// TODO: Add your specialized creation code here
CArray<CString,CString&> m_strErrors;
std::ifstream istrm(lpszPathName);
delete m_pPkg; m_pPkg = NULL;
TCHAR szTemp[2048];
szTemp[2047]=0;
m_aRules.RemoveAll();
for(;!istrm.eof() && !istrm.fail();)
{
docElement docEl;
CString str;
istrm.getline(szTemp,2047);
str = szTemp;
docEl.fSkip = false;
docEl.strError = "";
docEl.strLine = szTemp;
m_aRules.Add(docEl);
}
CString strErrors="";
ReloadPackage(strErrors);
if(!strErrors.IsEmpty())
AfxMessageBox(strErrors);
return TRUE;
}
BOOL CGrammarIDEDoc::OnSaveDocument(LPCTSTR lpszPathName)
{
if(IsModified())
{
UpdateAllViews(NULL,HINT_SAVEEDITOR);
SetModifiedFlag(FALSE);
}
CString strErrors;
int i;
for(i=0;i<m_aRules.GetSize();i++)
{
if(m_aRules[i].fSkip)
strErrors += m_aRules[i].strError;
}
if(!strErrors.IsEmpty())
{
strErrors = "The document has the following errors, should it be saved anyway?\r\n\r\n"+strErrors;
if(AfxMessageBox(
strErrors,
MB_ICONQUESTION|MB_YESNO)==IDNO)
return FALSE;
}
std::ofstream ostrm(lpszPathName);
for(i=0;i<m_aRules.GetSize();i++)
ostrm << ((LPCTSTR)m_aRules[i].strLine) << std::endl;
return TRUE;
}
void CGrammarIDEDoc::OnUpdateFileSave(CCmdUI* pCmdUI)
{
if(IsModified())
pCmdUI->Enable(TRUE); else pCmdUI->Enable(FALSE);
}
void CGrammarIDEDoc::OnParseReparse()
{
// TODO: Add your command handler code here
UpdateAllViews(NULL,HINT_SAVEEDITOR);
}
void CGrammarIDEDoc::OnEditRenumberIds()
{
// TODO: Add your command handler code here
UpdateAllViews(NULL,HINT_RENUMBER);
}
void CGrammarIDEDoc::OnEditRenumberIdsStrict()
{
// TODO: Add your command handler code here
UpdateAllViews(NULL,HINT_RENUMBER_STRICT);
}