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

📄 editorview.cpp

📁 一个完全使用MFC框架开发的C++编译器的代码。功能十分强大可以编译大型程序。
💻 CPP
📖 第 1 页 / 共 5 页
字号:
			HScrollTo(0);
	}
	else
		m_currentcolumn++;
	AdjustScroll();
	SetCaretPosition(true, true);
}
void CEditorView::CaretLeft()
{
	if (m_currentcolumn == 0)	{
		if (m_currentrow == 0)
			return;
		const std::string& str = GetDocument()->textline(--m_currentrow);
		m_currentcolumn = str.length();
	}
	else
		--m_currentcolumn;
	AdjustScroll();
	SetCaretPosition(false, true);
}

static bool iswordchar(char ch)
{
	return isalpha(ch) || isdigit(ch) || ch == '_';
}

void CEditorView::WordRight()
{
	int linect = GetDocument()->linecount();
	if (m_currentrow == linect)
		return;
	const std::string* str = &GetDocument()->textline(m_currentrow);
	if (str->empty())	{
		// --- sitting on a blank line
		CaretRight();
		return;
	}
	// --- move out of the current word
	bool testwdch = iswordchar((*str)[m_currentcolumn]);
	while (!isspace((*str)[m_currentcolumn]) && 
			iswordchar((*str)[m_currentcolumn]) == testwdch)	{
		if (m_currentrow == linect-1 && m_currentcolumn == str->length())
			return;		// at end of file
		CaretRight();
		if (m_currentcolumn == 0)	{
			if (m_currentrow == linect)
				return;
			str = &GetDocument()->textline(m_currentrow);
			break;
		}
	}
	// --- move to the next word
	while (!str->empty() && isspace((*str)[m_currentcolumn]))	{
		CaretRight();
		if (m_currentcolumn == 0)	{
			if (m_currentrow == linect)
				return;
			str = &GetDocument()->textline(m_currentrow);
		}
	}
}
void CEditorView::WordLeft()
{
	CaretLeft();
	if (m_currentrow == 0 && m_currentcolumn == 0)
		return;
	const std::string* str = &GetDocument()->textline(m_currentrow);
	if (str->empty())
		return;
	// --- move back out of spaces to previous word
	while (isspace((*str)[m_currentcolumn]))	{
		if (m_currentcolumn == 0)
			return;
		CaretLeft();
	}

	bool testwdch = iswordchar((*str)[m_currentcolumn]);
	while (iswordchar((*str)[m_currentcolumn]) == testwdch && 
				!isspace((*str)[m_currentcolumn]))	{
		if (m_currentcolumn == 0)
				return;
		CaretLeft();
	}
	CaretRight();
}
void CEditorView::LineEnd()
{
	const std::string& str = GetDocument()->textline(m_currentrow);
	m_currentcolumn = str.length();
	AdjustScroll();
	SetCaretPosition(false, true);
}
void CEditorView::LineHome()
{

	int lno = CurrentLineNumber();
	const std::string& line = GetDocument()->textline(lno-1);
	int len = line.length();
	int i;
	for (i = 0; i < len; i++)
		if (line[i] != '\t' && line[i] != ' ')
			break;
	m_currentcolumn = (i < len && m_currentcolumn > i) ? i : 0;
	if (m_leftcolumn > m_currentcolumn * m_fontwidth)
		HScrollTo(0);
	SetCaretPosition(false, true);
}

/////////////////////////////////////////////////////////////////////////
// Editing functions

void CEditorView::DeleteWord()
{
	m_buildcomments = true;
	if (IsSelectionMarked())
		DeleteSelection();
	CEditorDoc* pDoc = GetDocument();
	ASSERT(pDoc != 0);
	const std::string line = pDoc->textline(m_currentrow);

	int len = line.length();

	bool blankline = len == 0 && pDoc->linecount() < m_windowrows / m_fontheight;

	bool endofline = m_currentcolumn == len;

	if (blankline || endofline)	{
		DeleteCharacter();
		return;
	}

	int i = m_currentcolumn;
	if (isspace(line[i]))	{
		while (i < len && isspace(line[i]))	{
			pDoc->deletechar(m_currentrow, m_currentcolumn, i == m_currentcolumn);
			i++;
		}
	}
	else if (!isalpha(line[i]) && line[i] != '_')
		pDoc->deletechar(m_currentrow, m_currentcolumn);
	else	{
		do	{
			pDoc->deletechar(m_currentrow, m_currentcolumn, i == m_currentcolumn);
			i++;
		} while (i < len && (isalpha(line[i]) || line[i] == '_'));
		while (i < len && isspace(line[i]))	{
			pDoc->deletechar(m_currentrow, m_currentcolumn, false);
			i++;
		}
	}
	UpdateTextLine();
}

void CEditorView::DeleteCharacter()
{
	m_buildcomments = true;
	if (IsSelectionMarked())	{
		DeleteSelection();
		return;
	}

	CEditorDoc* pDoc = GetDocument();
	ASSERT(pDoc != 0);
	
	bool blankline = pDoc->textline(m_currentrow).length() == 0 && 
				pDoc->linecount() < m_windowrows / m_fontheight;

	if (pDoc->deletechar(m_currentrow, m_currentcolumn) && !blankline)
		UpdateTextLine();
	else
		Invalidate(false);
}
void CEditorView::SplitLine()
{
	m_buildcomments = true;
	bool bsel = IsSelectionMarked();
	if (bsel)
		DeleteSelection();
	// --- Enter key, split the current string in two
	GetDocument()->insertchar('\r', m_currentrow, m_currentcolumn, !bsel);
	HScrollTo(0);
	Invalidate(false);
}

void CEditorView::InsertTab()
{
	m_buildcomments = true;
	CEditorDoc* pDoc = GetDocument();
	ASSERT(pDoc != 0);
	int tabs = theApp.Tabstops();
	std::string blankstr(tabs, ' ');
	bool bt = theApp.TabOption() == 0;

	if (IsSelectionMarked())	{
		ViewIndex begin, end;
		m_pEditorSelection->GetSelectionMarkers(begin, end);
		if (end.column > 0)
			end.row++;
		m_pEditorSelection->SaveSelection();
		m_pEditorSelection->UnmarkSelection();
		m_currentcolumn = 0;
		bool bterminate = true;
		if (m_shiftdown)	{
			for (m_currentrow = begin.row; m_currentrow < end.row; m_currentrow++)	{
				if (pDoc->textline(m_currentrow)[0] == '\t')	{
					pDoc->deletechar(m_currentrow, 0, bterminate);
					bterminate = false;
				}
				else	{
					int t = tabs;
					if (pDoc->textline(m_currentrow).substr(0,tabs) == blankstr)	{
						while (t--)	{
							pDoc->deletechar(m_currentrow, 0, bterminate);
							bterminate = false;
						}
					}
				}
				UpdateTextLine();
			}
		}
		else	{
			for (m_currentrow = begin.row; m_currentrow < end.row; m_currentrow++)	{
				if (bt)	{
					pDoc->insertchar('\t', m_currentrow, 0, bterminate);
					bterminate = false;
				}
				else	{
					int t = tabs;
					while (t--)	{
						pDoc->insertchar(' ', m_currentrow, 0, bterminate);
						bterminate = false;
					}
				}
				UpdateTextLine();
			}
		}
		m_pEditorSelection->RestoreSelection();
		UpdateWindow();
	}
	else	{
		pDoc->insertchar(bt ? '\t' : ' ', m_currentrow, m_currentcolumn);
		while (++m_currentcolumn % tabs)
			if (!bt)
				pDoc->insertchar(' ', m_currentrow, m_currentcolumn);
		UpdateTextLine();
		AdjustScroll();
	}
	SetCaretPosition(false, true);
}
void CEditorView::InsertCharacter(char ch, bool bterminate)
{
	m_buildcomments = true;
	bool bsel = IsSelectionMarked();
	if (bsel)
		DeleteSelection();
	GetDocument()->insertchar(ch, m_currentrow, m_currentcolumn, (!bsel) && bterminate);
	if (ch == '/' || ch == '*' || ch == '"')
		Invalidate(false);
	else
		UpdateTextLine();
}
void CEditorView::UpdateTextLine()
{
	m_buildcomments = true;
	if ((m_selectionmarked = IsSelectionMarked()) == true)
		m_pEditorSelection->GetSelectionMarkers(m_start, m_stop);
	CClientDC dc(this);
	delete m_pClearBrush;
	m_pClearBrush = new CBrush(theApp.BackgroundColor());
	InsertLineIntoScreen(&dc, m_currentrow);
	delete m_pClearBrush;
	m_pClearBrush = 0;
}

void CEditorView::DeleteSelection(bool changecaret, bool bterminate)
{
	m_buildcomments = true;
	ViewIndex begin, end;
	m_pEditorSelection->GetSelectionMarkers(begin, end);
	m_pEditorSelection->UnmarkSelection();
	const std::string& str = GetDocument()->textline(begin.row);
	std::string newstr = str.substr(0, begin.column);
	if (begin.row == end.row)
		// --- the selection is all on one line
		newstr += str.substr(end.column, str.length() - end.column);
	else	{
		while (begin.row != end.row)	{
			GetDocument()->deleteline(begin.row, bterminate);
			if (!changecaret && begin.row < m_currentrow)
				--m_currentrow;
			bterminate = false;
			--end.row;
		}
		if (begin.row < GetDocument()->linecount() - 1)	{
			const std::string& str = GetDocument()->textline(begin.row);
			newstr += str.substr(end.column, str.length() - end.column);
		}
	}
	GetDocument()->replaceline(end.row, newstr, bterminate);
	Invalidate(false);

	if (changecaret)	{
		m_currentrow = begin.row;
		m_currentcolumn = begin.column;
	}
	else if (end.row == m_currentrow && end.column < m_currentcolumn)
		m_currentcolumn -= m_currentcolumn - end.column;
	SetCaretPosition();
}
/////////////////////////////////////////////////////////////////////////////
// marked selection functions
void CEditorView::InvertDisplayItems(ViewIndex begin, ViewIndex end)
{
	CRect rc;
	rc.top = begin.row * m_fontheight;
	rc.bottom = end.row * m_fontheight + m_fontheight;
	rc.left = 0;
	rc.right = m_windowcolumns;
	do	{
		int len;
		if (begin.row < end.row)	{
			len = GetDocument()->textline(begin.row).length();
			// --- if its an empty line, make it look like one space character
			if (len == 0)
				len = 1;
		}
		else
			len = end.column;
		InvertDisplayRow(begin.row, begin.column, len);
		begin.column = 0;
	} while (begin.row++ < end.row);
}

void CEditorView::InvertDisplayRow(unsigned int row, unsigned int begincol, unsigned int endcol)
{
	CRect rc;
	rc.left = begincol * m_fontwidth - m_leftcolumn + m_margin;
	rc.top = row * m_fontheight - m_toprow;
	rc.right = endcol * m_fontwidth - m_leftcolumn + m_margin;
	rc.bottom = rc.top + m_fontheight;
	CClientDC dc(this);
	dc.PatBlt(rc.left,rc.top,rc.Width(),rc.Height(),DSTINVERT);
}

/////////////////////////////////////////////////////////////////////////////
// CEditorView message handlers
void CEditorView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
	SCROLLINFO sivert = {sizeof(SCROLLINFO)};
	GetScrollInfo(SB_VERT, &sivert);
	nPos = sivert.nTrackPos;
	switch(nSBCode)	{
		case SB_TOP:
			VScrollTo(0);
			break;
		case SB_THUMBTRACK:
			VScrollTo(nPos);
			break;
		case SB_LINEDOWN:
			ScrollUp();
			break;
		case SB_LINEUP:
			ScrollDown();
			break;
		case SB_PAGEDOWN:
			PageDown();
			break;
		case SB_PAGEUP:
			PageUp();
			break;
		default:
			break;
	}
}

void CEditorView::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) 
{
	SCROLLINFO sihorz = {sizeof(SCROLLINFO)};
	GetScrollInfo(SB_HORZ, &sihorz);
	nPos = sihorz.nTrackPos;
	switch(nSBCode)	{
		case SB_LEFT:
			HScrollTo(0);
			break;
		case SB_LINELEFT:
			ScrollLeft();
			break;
		case SB_LINERIGHT:
			ScrollRight();
			break;
		case SB_PAGELEFT:
			PageLeft();
			break;
		case SB_PAGERIGHT:
			PageRight();
			break;
		case SB_THUMBTRACK:
			HScrollTo(nPos);
			break;
		default:
			break;
	}
}

// ------ convert screen coordinates to document character coordinates, 
//        adjusting for scroll position, and line lengths
CPoint CEditorView::ScreenToCharCoordinates(CPoint pt)
{
	if (pt.x < m_margin)
		pt.x = m_margin;
	int x = ((pt.x - m_margin) + m_leftcolumn) / m_fontwidth;
	int y = (pt.y + m_toprow) / m_fontheight;
	if (y >= GetDocument()->linecount())	{
		y = GetDocument()->linecount() - 1;
		if (y < 0)
			y = 0;
	}
	int wd = GetDocument()->textline(y).length();
	if (x > wd)
		x = wd;
	return CPoint(x, y);
}

// ------ convert document character coordinates to screen coordinates, 
CPoint CEditorView::CharToScreenCoordinates(CPoint pt)
{
	return CPoint(pt.x * m_fontwidth - m_leftcolumn + m_margin, pt.y * m_fontheight - m_toprow);
}

// ---- set the caret position adjusting for tabs in the text
void CEditorView::SetCaretPosition(bool bmoveright, bool frompaging)
{
	if (m_currentrow < 0)
		m_currentrow = 0;
	if (m_currentcolumn < 0)
		m_currentcolumn = 0;
	assert(GetDocument()->linecount() > 0);
	if (m_currentrow < GetDocument()->linecount())	{
		const std::string& str = GetDocument()->textline(m_currentrow);
		if (!str.empty())	{
			int i = m_currentcolumn;
			int tabs = theApp.Tabstops();
			while ((i % tabs) != 0 && str[i] == ' ')
				if (str[--i] == '\t')
					break;
			if (str[i] == '\t')	{
				if (i != m_currentcolumn && bmoveright)	{
					do
						i++;
					while ((i % tabs) != 0);
				}
				m_currentcolumn = i;
			}
		}
		if (m_currentcolumn > str.length())
			m_currentcolumn = str.length();
	}
	else	{
		m_currentrow = GetDocument()->linecount() - 1;
		m_currentcolumn = GetDocument()->textline(m_currentrow).length();
	}
	SetCaretPos(CharToScreenCoordinates(CPoint(m_currentcolumn, m_currentrow)));

	if (frompaging && m_pEditorSelection->IsMarking())
		m_pEditorSelection->ExtendSelection(ViewIndex(this, m_currentrow, m_currentcolumn));
	((CMainFrame*)theApp.m_pMainWnd)->SetRowColumn(m_currentrow+1, m_currentcolumn+1);
	ShowCaret();
}

void CEditorView::OnSetFocus(CWnd* pOldWnd) 
{
	CView::OnSetFocus(pOldWnd);
	CreateSolidCaret(2, m_fontheight);
	if (GetDocument()->linecount() > 0)
		SetCaretPosition();
}

void CEditorView::OnKillFocus(CWnd* pNewWnd) 
{
	CView::OnKillFocus(pNewWnd);
	((CMainFrame*)theApp.m_pMainWnd)->SetRowColumn(-1, -1);
	HideCaret();
	::DestroyCaret();
}

////////////////////////////////////////////////////////
// mouse functions

void CEditorView::OnLButtonDblClk(UINT nFlags, CPoint point) 
{
	if (!m_recording)	{
		m_pEditorSelection->UnmarkSelection();
		const std::string* str = &GetDocument()->textline(m_currentrow);
		if (!str->empty())	{
			if (iswordchar((*str)[m_currentcolumn]))	{
				while (m_currentcolumn > 0 && iswordchar((*str)[m_currentcolumn]))
					CaretLeft();
				if (!iswordchar((*str)[m_currentcolumn]))
					CaretRight();
				m_pEditorSelection->SetMarking(ViewIndex(this, m_currentrow, m_currentcolumn));
				do
					CaretRight();
				while (iswordchar((*str)[m_currentcolumn]));
				m_pEditorSelection->ExtendSelection(ViewIndex(this, m_currentrow, m_currentcolumn));
			}
		}

⌨️ 快捷键说明

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