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

📄 editorview.cpp

📁 一个完全使用MFC框架开发的C++编译器的代码。功能十分强大可以编译大型程序。
💻 CPP
📖 第 1 页 / 共 5 页
字号:
void CEditorView::OnEditPaste() 
{
	OpenClipboard();
	HANDLE hClipboardData = GetClipboardData(CF_TEXT);
	std::vector<std::string> strs;
	bool bsel = m_pEditorSelection->IsSelectionMarked();
	if (hClipboardData != 0)	{
		char* cp = (char*) GlobalLock(hClipboardData);
		if (cp != 0)	{
			if (bsel)
				DeleteSelection();
			// --- build a vector of strings from the clipboard \r\n terminated strings
			StringToVector(strs, cp);
		}
		GlobalUnlock(hClipboardData);
	}
	CloseClipboard();
	if (strs.size() > 0)	{
		InsertStringsIntoDocument(strs, !bsel);
		Invalidate(false);
		SetCaretPosition();
	}
}

////////////////////////////////////////////////////////
// search and replace functions

void CEditorView::OnEditFind() 
{
	m_ctrldown = false;			// in case of Ctrl+F
	FindReplace(true);
}

void CEditorView::OnEditReplace() 
{
	m_ctrldown = false;			// in case of Ctrl+H
	FindReplace(false);
}

void CEditorView::OnUpdateEditFindNext(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable(m_findtext.length() != 0);
}

void CEditorView::OnEditFindNext() 
{
	FindNext();
}

void CEditorView::FindReplace(bool findonly) 
{
	std::string str = SelectedText();
	if (!str.empty())
		m_findtext = str;
	m_pEditorSelection->UnmarkSelection();
	m_wasfound = m_found = m_bchanged = false;
	delete m_pFindDlg;
	m_pFindDlg = new CFindReplaceDialog;
	m_pFindDlg->Create(findonly, m_findtext.c_str(), m_replacetext.empty() ? 0 : m_replacetext.c_str(), m_nfrflags, this);
}

void CEditorView::FindNext()
{
	m_pEditorSelection->UnmarkSelection();
	if (m_nfrflags & FR_DOWN)
		FindTextForward();
	else
		FindTextBackward();
	if (m_found)	{
		int len = m_findtext.length();
		m_currentrow = m_findrow;
		m_currentcolumn = m_findcol;
		if (m_nfrflags & FR_DOWN)
			m_currentcolumn += len;
		else
			m_findcol += len;
		m_pEditorSelection->SetMarking(ViewIndex(this, m_findrow, m_findcol));
		m_pEditorSelection->ExtendSelection(ViewIndex(this, m_currentrow, m_currentcolumn));
		AdjustScrollQuietly();
	}
}

LONG CEditorView::OnFindReplace(WPARAM wParam, LPARAM lParam)
{
	LPFINDREPLACE fr = (LPFINDREPLACE)lParam;
	m_findtext = fr->lpstrFindWhat;
	m_replacetext = fr->lpstrReplaceWith;
	m_nfrflags = fr->Flags;

	if (m_nfrflags & FR_DIALOGTERM)	{
		m_pFindDlg = 0;
		m_wasfound = m_found = m_bchanged = false;
		m_nfrflags &= ~FR_DIALOGTERM;
		return 0;
	}
	
	int saverow = m_currentrow;
	int savecol = m_currentcolumn;

	if (m_nfrflags & FR_REPLACEALL)
		m_currentrow = m_currentcolumn = 0;
	bool bterminate = true;
	for (;;)	{
		if (((m_nfrflags & FR_REPLACE) || (m_nfrflags & FR_REPLACEALL)) && m_found)	{
			assert(m_pEditorSelection->IsSelectionMarked());
			ViewIndex start, stop;
			m_pEditorSelection->GetSelectionMarkers(start, stop);
			m_pEditorSelection->UnmarkSelection();
			assert(start.row == stop.row);
			assert(start.column < stop.column);
			const std::string& line = GetDocument()->textline(start.row);
			std::string first = line.substr(0, start.column);
			std::string last = line.substr(stop.column, line.length() - stop.column);
			std::string mid(m_replacetext);
			std::string line1 = first + mid + last;
			GetDocument()->replaceline(start.row, line1, bterminate);
			m_currentrow = start.row;
			m_currentcolumn = start.column + m_replacetext.length();
			bterminate = false;
			m_bchanged = true;
			m_buildcomments = true;
		}
		else
			m_pEditorSelection->UnmarkSelection();
		int len = m_findtext.length();
		FindNext();
		m_wasfound |= m_found;
		if (!m_found)	{
			if (!m_wasfound)	{
				CString msg("Cannot find \"");
				msg += m_findtext.c_str();
				msg += '"';
				AfxMessageBox(msg, MB_ICONEXCLAMATION);
				m_currentrow = saverow;
				m_currentcolumn = savecol;
			}
			break;
		}
		if (!(m_nfrflags & FR_REPLACEALL))
			break;
	}
	if (m_bchanged)
		AdjustScrollQuietly();
	return 0;
}

bool CEditorView::isword(const char* cp, int col, int len)
{
	if (col == 0 || isspace(cp[col-1]) || ispunct(cp[col-1]))
		if (cp[col + len] == '\0' || isspace(cp[col + len]) || ispunct(cp[col + len]))
			return true;
	return false;
}

void CEditorView::FindTextForward()
{
	m_found = false;
	m_findrow = m_currentrow;
	m_findcol = m_currentcolumn;
	int len = m_findtext.length();
	while (m_findrow < GetDocument()->linecount())	{
		const std::string& line = GetDocument()->textline(m_findrow);
		while (m_findcol + len <= line.length())	{
			bool whole = (m_nfrflags & FR_WHOLEWORD) != 0;
			if ((m_nfrflags & FR_MATCHCASE) == 0)	{
				if (strnicmp(m_findtext.c_str(), line.c_str() + m_findcol, len) == 0)	{
					if (!whole || isword(line.c_str(), m_findcol, len))	{
						m_found = true;
						return;
					}
				}
			}
			else if (strncmp(m_findtext.c_str(), line.c_str() + m_findcol, len) == 0)	{
				if (!whole || isword(line.c_str(), m_findcol, len))	{
					m_found = true;
					return;
				}
			}
			m_findcol++;
		}
		m_findcol = 0;
		m_findrow++;
	}
}

void CEditorView::FindTextBackward()
{
	m_found = false;
	m_findrow = m_currentrow;
	m_findcol = m_currentcolumn;
	int len = m_findtext.length();
	while (m_findrow >= 0)	{
		const std::string& line = GetDocument()->textline(m_findrow);
		m_findcol -= len;
		while (m_findcol >= 0)	{
			bool whole = (m_nfrflags & FR_WHOLEWORD) != 0;
			if ((m_nfrflags & FR_MATCHCASE) == 0)	{
				if (strnicmp(m_findtext.c_str(), line.c_str() + m_findcol, len) == 0)	{
					if (!whole || isword(line.c_str(), m_findcol, len))	{
						m_found = true;
						return;
					}
				}
			}
			else if (strncmp(m_findtext.c_str(), line.c_str() + m_findcol, len) == 0)	{
				if (!whole || isword(line.c_str(), m_findcol, len))	{
					m_found = true;
					return;
				}
			}
			--m_findcol;
		}
		if (--m_findrow >= 0)
			m_findcol = GetDocument()->textline(m_findrow).length();
	}
}

////////////////////////////////////////////////////////
// undo/redo functions

void CEditorView::OnEditUndo() 
{
	m_buildcomments = true;
	m_pEditorSelection->UnmarkSelection();
	GetDocument()->OnEditUndo();
}

void CEditorView::OnEditRedo() 
{
	m_buildcomments = true;
	m_pEditorSelection->UnmarkSelection();
	GetDocument()->OnEditRedo();
}

BOOL CEditorView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message) 
{
	SetCursor(m_recording ? m_hRecordCursor : m_hArrowCursor);
	return true;
}

void CEditorView::OnFileOpen() 
{
	m_buildcomments = true;
	m_ctrldown = false;			// in case of Ctrl+O
	theApp.OnFileOpen();
}

void CEditorView::OnFilePrint() 
{
	m_ctrldown = false;			// in case of Ctrl+P
	CView::OnFilePrint();
}

void CEditorView::OnUpdateFileSaveAll(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable(true);
}

// ------- brace matching
void CEditorView::OnUpdateBracematch(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable(IsSourceCodeFile() && CanMatchBraces());
}

void CEditorView::OnUpdateBeautify(CCmdUI* pCmdUI) 
{
	pCmdUI->Enable(pEditor == 0 && theApp.BeautifierIsInstalled() && IsSourceCodeFile());
}

// --- ensure that brace character is not character or string literal
//     and not in a comment
bool CEditorView::IsSpecificBrace(char ch, int row, int col)
{
	if (GetDocument()->textchar(row, col) != ch)
		return false;
	if (col > 0)	{
		if (IsCharLiteral(row, col))
			return false;
		if (IsContextElement(row, col))
			return false;
	}
	return true;
}

#ifdef _DEBUG
void CEditorView::DumpContextTable()
{
	std::set<CodeElement>::iterator iter;
	TRACE("\n -------- Context Table ----------");
	for (iter = m_contexttable.begin(); iter != m_contexttable.end(); iter++)	{
		CodeElement cmt = *iter;
		TRACE("\nLine %02d: Char %02d: Clr %06x", cmt.line, cmt.charpos, cmt.color);
	}
	TRACE("\n -------- End of Context Table ----------\n");
}
#endif

bool CEditorView::IsContextElement(int row, int col)
{
	CodeElement ce;
	ce.line = row;
	ce.charpos = col;

	std::set<CodeElement>::const_iterator it = std::lower_bound(m_contexttable.begin(), m_contexttable.end(), ce);
	if (it == m_contexttable.end())
		return false;
	if (it != m_contexttable.begin())
		--it;
	return (*it).color != theApp.NormalColor();
}

bool CEditorView::IsCharLiteral(int row, int col)
{
	const std::string& str = GetDocument()->textline(row);
	if (col < str.length()-1)	{
		if (GetDocument()->textchar(row, col-1) == '\'')
			if (GetDocument()->textchar(row, col+1) == '\'')
				return true;
	}
	return false;
}

void CEditorView::Beautify()
{
	PageHome();
	m_pEditorSelection->UnmarkSelection();
	beautifiedtext.clear();
	CString strExe = theApp.Enquote(theApp.QuincyBinPath() + "\\astyle.exe ");
	CString strArgs(theApp.BeautifierCommand());
	delete m_pConsoleApp;
	m_pConsoleApp = new ConsoleApp(strExe, &Notify, &Collect);
	try	{
		m_pConsoleApp->Run(strArgs);

		int lines = GetDocument()->linecount();
		if (lines != 0) {
			for (int i = 0; i < lines; i++) {
				std::string str = GetDocument()->textline(i);
				CEditorDoc::entab(str);
				m_pConsoleApp->WriteConsole(str.c_str());
//				TRACE("\nOUT: %s", str.c_str());
			}
		}
		char ctrlz[2] = {26,0};
		m_pConsoleApp->WriteConsole(ctrlz);
	}
	catch(...)	{
		AfxMessageBox("\nCannot execute Astyle", MB_ICONSTOP);
	}
}

// --- called from the console application thread while beautifying is going on
void CEditorView::Collect(DWORD bufct)
{
	ASSERT(pEditor != 0);
	pEditor->CollectSourceLines(bufct);
}

void CEditorView::CollectSourceLines(DWORD bufct)
{
	char *line = new char[bufct+1];
	ASSERT(m_pConsoleApp);
	if (m_pConsoleApp->ReadConsole(line, bufct) != 0)	{
//		TRACE("\nIN:  %s", line);
		std::string str(line);
		CEditorDoc::detab(str);
		beautifiedtext.push_back(str);
	}
	delete [] line;
}

void CEditorView::Notify()
{
	ASSERT(pEditor != 0);
	pEditor->NotifyTermination();
}

void CEditorView::NotifyTermination()
{
//	TRACE("\n---done---\n");
	beautifiedtext.push_back(std::string());
	GetDocument()->ReplaceDocument(beautifiedtext);
	beautifiedtext.clear();
	BuildContextHighlightTable();
	Invalidate(TRUE);
	delete m_pConsoleApp;
	m_pConsoleApp = 0;
	pEditor = 0;
}

void CEditorView::OnBeautify()
{
	CBeautifier bt;
	bt.m_style = theApp.BeautifierStyle();
	bt.m_Cmdline = theApp.BeautifierCommand();
	if (bt.DoModal() == IDOK)	{
		pEditor = this;
		theApp.SetBeautifierStyle(bt.m_style);
		theApp.SetBeautifierCommand(bt.m_Cmdline);
		Beautify();
	}
}

void CEditorView::OnBracematch()
{

#ifdef _DEBUG
//	DumpContextTable();
#endif

	// --- these are zero-based
	int row = m_currentrow;
	int col = m_currentcolumn;

	int lines = GetDocument()->linecount();

	if (IsLeftBrace(row, col))	{
		int nests = 0;
		bool bmatch = false;
		while (row < lines)	{
			int len = GetDocument()->textline(row).length();
			while (col < len)	{
				if (IsLeftBrace(row, col))
					nests++;
				else if (IsRightBrace(row, col))	{
					if ((bmatch = --nests == 0) == true)
						break;
				}
				if (bmatch)
					break;
				col++;
			}
			if (bmatch)
				break;
			row++;
			col = 0;
		}
		if (bmatch)	{
			m_currentrow = row;
			m_currentcolumn = col;
			AdjustScrollQuietly();
		}
		else	{
			AfxMessageBox("No matching '}'", MB_ICONSTOP);
			m_ctrldown = false;
		}
	}
	else if (IsRightBrace(row, col))	{
		int nests = 0;
		bool bmatch = false;
		while (row >= 0)	{
			while (col >= 0)	{
				if (IsRightBrace(row, col))
					nests++;
				else if (IsLeftBrace(row, col))	{
					if ((bmatch = --nests == 0) == true)
						break;
				}
				if (bmatch)
					break;
				--col;
			}
			if (bmatch)
				break;
			if (--row >= 0)
				col = GetDocument()->textline(row).length() - 1;
		}
		if (bmatch)	{
			m_currentrow = row;
			m_currentcolumn = col;
			AdjustScrollQuietly();
		}
		else
			AfxMessageBox("No matching '}'", MB_ICONSTOP);
	}
}


// ---- Editor calls this function for every character typed.
//      Use the CEditorView and CEditorDoc APIs to extend the editor.
//      return true if you don't want Editor to further process the keystroke
bool CEditorView::ExtendEditor(UINT nChar)
{
	if (theApp.AutoIndentOption() && nChar == VK_RETURN)	{
		AutoIndent();
		return true;
	}
	
	return false;
}
// --- automatic indenting puts insertion caret and any following text
//     under leftmost character of previous line after user presses Enter key
void CEditorView::AutoIndent()
{
	int lno = CurrentLineNumber(); // one-based line number
	ASSERT(lno > 0);
	const std::string& line = GetDocument()->textline(lno-1);  // zero-based to get current line
	SplitLine();
	CaretRight();
	int len = line.length();
	int i;
	for (i = 0; i < len; i++)
		if (line[i] != '\t' && line[i] != ' ')

⌨️ 快捷键说明

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