⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 editordoc.cpp

📁 一个完全使用MFC框架开发的C++编译器的代码。功能十分强大可以编译大型程序。
💻 CPP
字号:
// EditorDoc.cpp : implementation of the CEditorDoc class
//

#include "stdafx.h"
#include <cassert>
#include "Quincy.h"

#include "EditorDoc.h"
#include "EditorView.h"
#include "EditorUndo.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

bool UndoEditorData::reportedundofull = false;

void UndoEditorData::TestUndoFull()
{
	if (WasUndoDataDiscarded() && !reportedundofull)	{
		reportedundofull = true;
		AfxMessageBox(
			"The Undo buffer is at capacity.\n"
			"Older undos are being discarded.\n"
			"Consider increasing Maximum Undos\n"
			"on Tools/Options/Editor");
	}
}

/////////////////////////////////////////////////////////////////////////////
// CEditorDoc

IMPLEMENT_DYNCREATE(CEditorDoc, CDocument)

BEGIN_MESSAGE_MAP(CEditorDoc, CDocument)
	//{{AFX_MSG_MAP(CEditorDoc)
	ON_UPDATE_COMMAND_UI(ID_EDIT_UNDO, OnUpdateEditUndo)
	ON_COMMAND(ID_EDIT_UNDO, OnEditUndo)
	ON_UPDATE_COMMAND_UI(ID_EDIT_REDO, OnUpdateEditRedo)
	ON_COMMAND(ID_EDIT_REDO, OnEditRedo)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CEditorDoc construction/destruction


CEditorDoc::CEditorDoc()
{
	m_pUndoEditorData = 0;
	m_linewidth = 0;
	BuildEmptyDocument();
}

CEditorDoc::~CEditorDoc()
{
	delete m_pUndoEditorData;
}

void CEditorDoc::BuildEmptyDocument()
{
	doctext.clear();
	m_linewidth = 0;
	std::string str("");
	doctext.push_back(str);
	ResetUndoData();
}

void CEditorDoc::ResetUndoData()
{
	delete m_pUndoEditorData;
	m_pUndoEditorData = new UndoEditorData(this, theApp.MaxUndos());
	undorow = undocolumn = -1;
}

BOOL CEditorDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
	return CDocument::OnOpenDocument(lpszPathName);
}

BOOL CEditorDoc::OnNewDocument()
{
	if (!CDocument::OnNewDocument())
		return false;
	if (!theApp.IsProjectFileLoaded())
		theApp.CloseErrorLog();
	BuildEmptyDocument();
	return true;
}

void CEditorDoc::replaceline(unsigned int lineno, const std::string& str, bool bterminate)
{
	undorow = undocolumn = -1;
	if (m_pUndoEditorData)
		m_pUndoEditorData->AddReplaceStrUndo(this, StrPosition(lineno), bterminate);
	doctext[lineno] = str;
	m_linewidth = max(m_linewidth, str.length());
	SetModifiedFlag();
}
void CEditorDoc::insertline(unsigned int lineno, const std::string& str, bool bterminate)
{
	undorow = undocolumn = -1;
	if (m_pUndoEditorData)
		m_pUndoEditorData->AddInsertStrUndo(this, StrPosition(lineno), bterminate);
	std::vector<std::string>::iterator iter = &doctext[lineno];
	doctext.insert(iter, str);
	m_linewidth = max(m_linewidth, str.length());
	theApp.InsertedTextLine(GetPathName(), lineno);
	SetModifiedFlag();
}
void CEditorDoc::deleteline(unsigned int lineno, bool bterminate)
{
	undorow = undocolumn = -1;
	if (lineno < doctext.size())	{
		if (m_pUndoEditorData)
			m_pUndoEditorData->AddDeleteStrUndo(this, StrPosition(lineno), bterminate);
		std::vector<std::string>::iterator iter = &doctext[lineno];
		doctext.erase(iter);
		if (doctext.size() == 0)	{
			std::string str("");
			doctext.push_back(str);
		}
		theApp.DeletedTextLine(GetPathName(), lineno);
		SetModifiedFlag();
	}
}
void CEditorDoc::appendline(const std::string& str, bool bterminate)
{
	undorow = undocolumn = -1;
	if (m_pUndoEditorData)
		m_pUndoEditorData->AddInsertStrUndo(this, StrPosition(doctext.size()), bterminate);
	doctext.push_back(str);
	m_linewidth = max(m_linewidth, str.length());
	SetModifiedFlag();
}

void CEditorDoc::insertchar(char ch, unsigned int row, unsigned int column, bool bterminate)
{
	SetModifiedFlag();
	std::string& str = doctext[row];
	if (ch == '\r')	{
		undorow = undocolumn = -1;
		std::string strleft  = str.substr(0, column);
		std::string strright = str.substr(column, str.length() - column);
		replaceline(row, strleft, bterminate);
		insertline(row + 1, strright, false);
		return;
	}
	if (m_pUndoEditorData)	{
		bool bulkundos = (ch == '\t' || row != undorow || column != undocolumn + 1);
		undorow = row;
		undocolumn = column;
		m_pUndoEditorData->AddInsertCharUndo(this, CharPosition(row, column), bterminate && bulkundos);
	}
	str.insert(column, std::string(1, ch));
	if (ch == '\t')	{
		int tabs = theApp.Tabstops();
		while (++column % tabs)
			str.insert(column, std::string(1, ' '));
	}
	m_linewidth = max(m_linewidth, str.length());
}

// --- delete a character. return true if deleting from inside text line
bool CEditorDoc::deletechar(unsigned int row, unsigned int column, bool bterminate)
{
	undorow = undocolumn = -1;
	SetModifiedFlag();
	std::string& str = doctext[row];
	if (column == str.length())	{
		// --- deleting the \n at the end of the text line
		if (row + 1 < doctext.size())	{
			std::string str1 = str;
			str1 += doctext[row + 1];
			replaceline(row, str1, bterminate);
			deleteline(row + 1, false);
		}
		return false;
	}
	// ---- deleting a character from within the text line
	if (m_pUndoEditorData)
		m_pUndoEditorData->AddDeleteCharUndo(this, CharPosition(row, column), bterminate);
	char ch = str[column];
	str.erase(column, 1);
	int tabs = theApp.Tabstops();
	if (ch == '\t')	{
		// --- deleting a tab; delete the trailing padding spaces
		int x = column;
		while ((++x) % tabs)
			str.erase(column, 1);
	}
	else if (ch == '/' || ch == '*')
		return false;
	return true;
}

/////////////////////////////////////////////////////////////////////////////
// CEditorDoc serialization

void CEditorDoc::detab(std::string& str, int tabstops)
{
	int x = 0;
	std::string newstr;
	int tabs = tabstops == -1 ? theApp.Tabstops() : tabstops;

	for (int i = 0; i < str.length(); i++)	{
		char ch = str[i];
		newstr += ch;
		x++;
		if (ch == '\t')	{
			while (x % tabs)	{
				newstr += ' ';
				x++;
			}
		}
	}
	str = newstr;
}

void CEditorDoc::entab(std::string& str)
{
	int x = 0;
	std::string newstr;
	int tabs = theApp.Tabstops();

	for (int i = 0; i < str.length(); i++)	{
		char ch = str[i];
		newstr += ch;
		x++;
		if (ch == '\t')	{
			while (x % tabs)	{
				i++;
				x++;
			}
		}
	}
	str = newstr;
}

void CEditorDoc::Retab(int newtabstops)
{
	std::vector<std::string>::iterator iter;
	for (iter = doctext.begin(); iter != doctext.end(); iter++)	{
		entab(*iter);
		detab(*iter, newtabstops);
	}
}

void CEditorDoc::Serialize(CArchive& ar)
{
	CString strText;
	if (ar.IsStoring())	{
		std::vector<std::string>::iterator iter;
		for (iter = doctext.begin(); iter != doctext.end(); iter++)	{
			std::string str(*iter);
			entab(str);
			str += "\r\n";
			strText = str.c_str();
			ar.WriteString(strText);
		}
	}
	else	{
//		if (theApp.GetProjectDocument() == 0)
//			theApp.ClearBreakpoints();
		doctext.clear();
		int linecount = 0;
		while (ar.ReadString(strText))	{
			std::string str(strText.GetBuffer(0));
			detab(str);
			doctext.push_back(str);
			m_linewidth = max(m_linewidth, str.length());
		}
	}
	ResetUndoData();
}

/////////////////////////////////////////////////////////////////////////////
// CEditorDoc diagnostics

#ifdef _DEBUG
void CEditorDoc::AssertValid() const
{
	CDocument::AssertValid();
}

void CEditorDoc::Dump(CDumpContext& dc) const
{
	CDocument::Dump(dc);
}
#endif //_DEBUG

////////////////////////////////////////////////////////
//
// Undo/Redo functions
//
// --- called from within undo/redo library
void CEditorDoc::Insert(StrPosition pos, const std::string& rStr)
{
	std::vector<std::string>::iterator iter = &doctext[pos.row];
	doctext.insert(iter, rStr);
	theApp.InsertedTextLine(GetPathName(), pos.row);
	UpdateView();
}
void CEditorDoc::Delete(StrPosition pos)
{
	std::vector<std::string>::iterator iter = &doctext[pos.row];
	doctext.erase(iter);
	theApp.DeletedTextLine(GetPathName(), pos.row);
	UpdateView();
}

void CEditorDoc::Replace(DocPosition pos, const std::vector<std::string>& rDoc)
{
	doctext.clear();
	doctext = rDoc;
	UpdateView();
}

const std::vector<std::string> CEditorDoc::GetDatum(DocPosition)
{
	return doctext;
}
void CEditorDoc::Replace(StrPosition pos, const std::string& rStr)
{
	doctext[pos.row] = rStr;
	UpdateView();
}
const std::string& CEditorDoc::GetDatum(StrPosition pos)
{
	return doctext[pos.row];
}
void CEditorDoc::Insert(CharPosition pos, char Char)
{
	insertchar(Char, pos.row, pos.column);
	UpdateView();
}
void CEditorDoc::Delete(CharPosition pos)
{
	deletechar(pos.row, pos.column);
	UpdateView();
}
void CEditorDoc::Replace(CharPosition pos, char Char)
{
	deletechar(pos.row, pos.column);
	insertchar(Char, pos.row, pos.column);
	UpdateView();
}
char CEditorDoc::GetDatum(CharPosition pos)
{
	return doctext[pos.row][pos.column];
}
CEditorView* CEditorDoc::GetView() const
{
	CEditorView* pView = 0;
	POSITION pos = GetFirstViewPosition();
	if (pos != 0)
		pView = static_cast<CEditorView*>(GetNextView(pos));
	return pView;
}
void CEditorDoc::UpdateView()
{
	CEditorView* pView = GetView();
	if (pView != 0)
		pView->Invalidate(false);
}
void CEditorDoc::SetUndoContext(ViewContext vc)
{
	CEditorView* pView = GetView();
	ASSERT(pView != 0);
	pView->SetCurrentPosition(vc.scroller.row, vc.scroller.column, vc.pos.row, vc.pos.column);
}
ViewContext CEditorDoc::GetUndoContext() const
{
	CEditorView* pView = GetView();
	ASSERT(pView != 0);
	ViewContext vc;
	pView->GetCurrentPosition(vc.scroller.row, vc.scroller.column, vc.pos.row, vc.pos.column);
	return vc;
}


/////////////////////////////////////////////////////////////////////////////
// CEditorDoc commands


bool CEditorDoc::CanUndo() const
{
	return m_pUndoEditorData ? m_pUndoEditorData->IsUndoDataStored() : false;
}
bool CEditorDoc::CanRedo() const
{
	return m_pUndoEditorData ? m_pUndoEditorData->IsRedoDataStored() : false;
}

void CEditorDoc::OnUpdateEditUndo(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable(CanUndo());
}

void CEditorDoc::OnEditUndo() 
{
	if (m_pUndoEditorData)	{
		m_pUndoEditorData->UndoLastAction();
		if (!m_pUndoEditorData->WasUndoDataDiscarded())
			if (!m_pUndoEditorData->IsUndoDataStored())
				SetModifiedFlag(false);
	}
}

void CEditorDoc::OnUpdateEditRedo(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable(CanRedo());
}

void CEditorDoc::OnEditRedo() 
{
	if (m_pUndoEditorData)	{
		m_pUndoEditorData->RedoLastUndo();
		if (m_pUndoEditorData->IsUndoDataStored())
			SetModifiedFlag(true);
	}
}


BOOL CEditorDoc::OnSaveDocument(LPCTSTR lpszPathName) 
{
	BOOL rtn = CDocument::OnSaveDocument(lpszPathName);
	CEditorView* pView = GetView();
	ASSERT(pView != 0);
	pView->ResetKeywords();	
	return rtn;
}

void CEditorDoc::ReplaceDocument(std::vector<std::string>& newdoc)
{
	theApp.ClearBreakpoints();

	undorow = undocolumn = -1;
	if (m_pUndoEditorData)
		m_pUndoEditorData->AddReplaceDocUndo(this, DocPosition(), true);

	doctext.clear();
	doctext = newdoc;
	SetModifiedFlag(true);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -