📄 editorview.cpp
字号:
pDC->SetTextColor(color);
int x = m_margin + beg * m_fontwidth - m_leftcolumn;
int top = line * m_fontheight - m_toprow;
pDC->ExtTextOut(x, top, ETO_CLIPPED, &rc, str.c_str(), len, 0);
}
void CEditorView::DisplaySourceText(CDC* pDC, int line)
{
const std::string& str = GetDocument()->textline(line);
if (theApp.SyntaxColorsOption() && IsSourceCodeFile()) {
CodeElement ce;
ce.line = line;
ce.charpos = 0;
std::set<CodeElement>::const_iterator it = m_contexttable.find(ce);
ASSERT(it != m_contexttable.end()); // must be an entry for char 0 of every line
do {
COLORREF clr = (*it).color;
int beg = ce.charpos;
int end = str.length();
if (++it != m_contexttable.end()) {
ce = *it;
if (ce.line == line)
end = ce.charpos;
}
DisplayText(pDC, beg, end-beg, line, clr);
} while (ce.line == line && it != m_contexttable.end());
}
else
// --- not a source code file or syntax color option not selected
DisplayText(pDC, 0, str.length(), line, theApp.NormalColor());
}
void CEditorView::InsertLineIntoScreen(CDC* pDC, unsigned int line)
{
HideCaret();
if (m_buildcomments) {
if (theApp.SyntaxColorsOption() && IsSourceCodeFile())
BuildContextHighlightTable();
m_buildcomments = false;
}
const std::string& str = GetDocument()->textline(line);
int len = str.length();
// --- display the text on the line
CFont* pOldFont = pDC->SelectObject(m_pscreenfont);
DisplaySourceText(pDC, line);
int top = line * m_fontheight - m_toprow;
// --- pad the line with spaces
len -= m_leftcolumn / m_fontwidth;
CRect rc(m_margin, top, m_windowcolumns, top + m_fontheight);
rc.left += len * m_fontwidth;
pDC->FillRect(&rc, m_pClearBrush);
pDC->SelectObject(pOldFont);
if (m_selectionmarked && line >= m_start.row && line <= m_stop.row) {
// ---- this line is in the selection, need to do some inverting in the bitmap
int left = m_margin - m_leftcolumn;
if (line == m_start.row)
left += m_start.column * m_fontwidth;
int right = m_margin + (line < m_stop.row ? len : m_stop.column) * m_fontwidth;
// for blank line display as if there is one space character
if (left == right && right == m_margin)
right += m_fontwidth;
int wd = right - left;
if (wd)
pDC->PatBlt(left, top, wd, m_fontheight, DSTINVERT);
}
ShowCaret();
UpdateTitle(GetDocument());
}
bool CEditorView::IsSourceFile(const CString& ext)
{
CDocument* pDoc = GetDocument();
if (pDoc != 0) {
CString strPath = pDoc->GetPathName();
return strPath.Right(ext.GetLength()).CompareNoCase(ext) == 0;
}
return false;
}
void CEditorView::OnDraw(CDC* pDC)
{
if (GetDocument() == 0)
return;
delete m_pClearBrush;
m_pClearBrush = new CBrush(theApp.BackgroundColor());
if (keywords.empty()) {
int i;
bool isc = IsCFile();
bool ish = IsHFile();
bool iscpp = IsCPPFile();
bool isrc = IsRCFile();
if (isrc)
for (i = 0; i < 12; i++)
keywords.insert(ckeys[i]);
if (isc || ish || iscpp)
for (i = 0; i < sizeof(ckeys) / sizeof(std::string); i++)
keywords.insert(ckeys[i]);
if (iscpp || ish)
for (i = 0; i < sizeof(cppkeys) / sizeof(std::string); i++)
keywords.insert(cppkeys[i]);
}
HideCaret();
CRect rc;
GetClientRect(&rc);
m_windowrows = rc.bottom;
m_windowcolumns = rc.right;
unsigned int linecount = GetDocument()->linecount();
m_bottomrow = linecount * m_fontheight;
m_linewidth = GetDocument()->linewidth() * m_fontwidth;
SCROLLINFO sivert = {
sizeof (SCROLLINFO),
SIF_RANGE,
0, m_bottomrow,
};
SCROLLINFO sihorz = {
sizeof (SCROLLINFO),
SIF_RANGE,
0, m_linewidth,
};
SetScrollInfo(SB_VERT, &sivert);
SetScrollInfo(SB_HORZ, &sihorz);
unsigned int line = m_toprow / m_fontheight;
unsigned int windowlines = (m_toprow + m_windowrows + m_fontheight) / m_fontheight;
linecount = min(linecount, windowlines);
if ((m_selectionmarked = IsSelectionMarked()) == true)
m_pEditorSelection->GetSelectionMarkers(m_start, m_stop);
while (line < linecount)
InsertLineIntoScreen(pDC, line++);
unsigned int lastrow = line * m_fontheight - m_toprow; // last window row drawn
if (lastrow < m_windowrows) {
// --- pad to the bottom of the window with spaces
CRect crc(rc);
crc.left = m_margin;
crc.top = lastrow;
pDC->FillRect(&crc, m_pClearBrush);
}
delete m_pClearBrush;
m_pClearBrush = 0;
PadMargin();
}
void CEditorView::PadMargin()
{
// ----- pad the left margin with a gray tone
CDC* pDC = GetDC(); // to pad the whole margin to avoid having to erase margin characters
CRect rc;
GetClientRect(&rc);
rc.right = m_margin;
pDC->FillRect(&rc, m_pMarginBrush);
ShowCaret();
}
/////////////////////////////////////////////////////////////////////////////
// CEditorView printing
BOOL CEditorView::OnPreparePrinting(CPrintInfo* pInfo)
{
delete pInfo->m_pPD; // framework has one built on heap
pInfo->m_pPD = new CQuincyPrintDialog; // framework will delete this object
static_cast<CQuincyPrintDialog*>(pInfo->m_pPD)->printlinenumbers = theApp.PrintLineNumbers();
return DoPreparePrinting(pInfo);
}
void CEditorView::OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo)
{
printlinenos = static_cast<CQuincyPrintDialog*>(pInfo->m_pPD)->printlinenumbers;
int nHeight = -((pDC->GetDeviceCaps(LOGPIXELSY) * 10) / 72);
m_printerfont.CreateFont(nHeight, 0, 0, 0, FW_NORMAL, 0, 0, 0,
DEFAULT_CHARSET, OUT_CHARACTER_PRECIS, CLIP_CHARACTER_PRECIS,
DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Courier");
TEXTMETRIC tm;
CFont* pOldFont = pDC->SelectObject(&m_printerfont);
pDC->GetTextMetrics(&tm);
m_cyPrinter = tm.tmHeight + tm.tmExternalLeading;
pDC->SelectObject(pOldFont);
m_nLinesPerPage =(pDC->GetDeviceCaps(VERTRES) -
(m_cyPrinter * (3 + (2 * PRINTMARGIN)))) / m_cyPrinter;
UINT nMaxPage = max(1, (GetDocument()->linecount() + (m_nLinesPerPage - 1)) /
m_nLinesPerPage);
pInfo->SetMaxPage(nMaxPage);
}
void CEditorView::OnPrint (CDC* pDC, CPrintInfo* pInfo)
{
PrintPageHeader(pDC, pInfo->m_nCurPage);
PrintPage(pDC, pInfo->m_nCurPage);
}
void CEditorView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* pInfo)
{
m_printerfont.DeleteObject ();
bool plno = static_cast<CQuincyPrintDialog*>(pInfo->m_pPD)->printlinenumbers;
theApp.SetPrintLineNumbers(plno);
}
void CEditorView::PrintPageHeader(CDC* pDC, UINT nPageNumber)
{
CString strHeader = GetDocument()->GetTitle();
CString strPageNumber;
strPageNumber.Format(" (Page %d)", nPageNumber);
strHeader += strPageNumber;
UINT y = m_cyPrinter * PRINTMARGIN;
CFont* pOldFont = pDC->SelectObject(&m_printerfont);
pDC->TextOut(0, y, strHeader);
pDC->SelectObject(pOldFont);
}
void CEditorView::PrintPage (CDC* pDC, UINT nPageNumber)
{
int lines = GetDocument()->linecount();
if (GetDocument()->linecount() != 0) {
UINT nStart = (nPageNumber - 1) * m_nLinesPerPage;
UINT nEnd = min(lines - 1, nStart + m_nLinesPerPage - 1);
CFont* pOldFont = pDC->SelectObject(&m_printerfont);
for (int i = nStart; i <= nEnd; i++) {
std::string str = GetDocument()->textline(i);
for (int j = 0; j < str.length(); j++)
if (str[j] == '\t')
str[j] = ' ';
int y = ((i - nStart) + PRINTMARGIN + 3) * m_cyPrinter;
CString line;
if (printlinenos)
line.Format("%-4d ", i + 1);
line += str.c_str();
pDC->TextOut(0, y, line);
}
pDC->SelectObject(pOldFont);
}
}
/////////////////////////////////////////////////////////////////////////////
// CEditorView diagnostics
#ifdef _DEBUG
void CEditorView::AssertValid() const
{
CView::AssertValid();
}
void CEditorView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CEditorDoc* CEditorView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument == 0 || m_pDocument->IsKindOf(RUNTIME_CLASS(CEditorDoc)));
return (CEditorDoc*)m_pDocument;
}
#endif //_DEBUG
////////////////// scrolling and paging functions
void CEditorView::SetScrollPosition(int nBar, UINT nPos)
{
SCROLLINFO si = {
sizeof(SCROLLINFO),
SIF_POS,
0,0,0,
nPos
};
SetScrollInfo(nBar, &si);
}
void CEditorView::VScrollTo(UINT nPos)
{
if (m_toprow != nPos) {
m_toprow = nPos;
SetScrollPosition(SB_VERT, nPos);
SetCaretPosition();
Invalidate(false);
}
}
void CEditorView::HScrollTo(UINT nPos)
{
if (m_leftcolumn != nPos) {
m_leftcolumn = nPos;
SetScrollPosition(SB_HORZ, nPos);
SetCaretPosition();
Invalidate(false);
}
}
void CEditorView::ScrollDown()
{
if (m_toprow > 0) {
int nsize = m_toprow < vscrollsize() ? m_toprow : vscrollsize();
CRect rc;
GetClientRect(&rc);
rc.left += m_margin;
ScrollWindow(0, nsize, &rc, &rc);
m_toprow -= nsize;
UpdateWindow();
SetScrollPosition(SB_VERT, m_toprow);
SetCaretPosition();
}
}
void CEditorView::ScrollUp()
{
if (GetScrollPos(SB_VERT) < m_toprow + vscrollsize()) {
CRect rc;
GetClientRect(&rc);
rc.left += m_margin;
ScrollWindow(0, -vscrollsize(), &rc, &rc);
m_toprow += vscrollsize();
UpdateWindow();
SetScrollPosition(SB_VERT, m_toprow);
SetCaretPosition();
}
}
void CEditorView::ScrollLeft()
{
if (m_leftcolumn > 0) {
int nsize = m_leftcolumn < hscrollsize() ? m_leftcolumn : hscrollsize();
CRect rc;
GetClientRect(&rc);
rc.left += m_margin;
ScrollWindow(nsize, 0, 0, &rc);
m_leftcolumn -= nsize;
UpdateWindow();
SetScrollPosition(SB_HORZ, m_leftcolumn);
SetCaretPosition();
}
}
void CEditorView::ScrollRight()
{
if (GetScrollPos(SB_HORZ) < m_leftcolumn + hscrollsize()) {
CRect rc;
GetClientRect(&rc);
rc.left += m_margin;
ScrollWindow(-hscrollsize(), 0, 0, &rc);
m_leftcolumn += hscrollsize();
UpdateWindow();
SetScrollPosition(SB_HORZ, m_leftcolumn);
SetCaretPosition();
}
}
void CEditorView::PageLeft()
{
if (m_leftcolumn > 0) {
m_leftcolumn -= hpagesize();
if (m_leftcolumn < 0)
m_leftcolumn = 0;
CRect rc;
GetClientRect(&rc);
rc.left += m_margin;
SetScrollPosition(SB_HORZ, m_leftcolumn);
ScrollWindow(hpagesize(), 0, &rc, &rc);
SetCaretPosition(false, true);
}
}
void CEditorView::PageRight()
{
if (GetScrollPos(SB_HORZ) < m_leftcolumn + hpagesize()) {
m_leftcolumn += hpagesize();
CRect rc;
GetClientRect(&rc);
rc.left += m_margin;
ScrollWindow(-hpagesize(), 0, &rc, &rc);
SetScrollPosition(SB_HORZ, m_leftcolumn);
SetCaretPosition(false, true);
}
}
void CEditorView::PageHome()
{
VScrollTo(0);
HScrollTo(0);
m_currentrow = 0;
m_currentcolumn = 0;
SetCaretPosition(false, true);
}
void CEditorView::PageEnd()
{
int nto = m_bottomrow - vpagesize();
VScrollTo(nto > 0 ? nto : 0);
HScrollTo(0);
m_currentrow = GetDocument()->linecount();
m_currentcolumn = 0;
SetCaretPosition(false, true);
}
void CEditorView::PageUp()
{
if (m_toprow > 0) {
m_toprow -= vpagesize();
if (m_toprow < 0)
m_toprow = 0;
Invalidate(false);
SetScrollPosition(SB_VERT, m_toprow);
SetCaretPosition(false, true);
}
}
void CEditorView::PageDown()
{
if (m_toprow + vpagesize() < m_bottomrow) {
m_toprow += vpagesize();
Invalidate(false);
SetScrollPosition(SB_VERT, m_toprow);
SetCaretPosition(false, true);
}
}
////////////////////////////////////////////////
// Functions for getting current position into view
void CEditorView::AdjustScroll()
{
int col = m_currentcolumn * m_fontwidth;
while (col > m_windowcolumns + m_leftcolumn - m_fontwidth)
PageRight();
while (col < m_leftcolumn)
PageLeft();
int row = m_currentrow * m_fontheight;
while (row > m_windowrows + m_toprow - m_fontheight)
ScrollUp();
while (row < m_toprow)
ScrollDown();
}
void CEditorView::AdjustScrollQuietly()
{
int col = m_currentcolumn * m_fontwidth;
while (col > m_windowcolumns + m_leftcolumn - m_fontwidth) {
if (GetScrollPos(SB_HORZ) < m_leftcolumn + hpagesize())
m_leftcolumn += hpagesize();
}
while (col < m_leftcolumn) {
if (m_leftcolumn > 0) {
m_leftcolumn -= hpagesize();
if (m_leftcolumn < 0)
m_leftcolumn = 0;
}
}
CurrentLineIntoView();
}
void CEditorView::CurrentLineIntoView()
{
int row = m_currentrow * m_fontheight;
if (row > m_windowrows + m_toprow - m_fontheight)
while (row > m_windowrows/2 + m_toprow - m_fontheight)
m_toprow += vscrollsize();
if (row < m_toprow) {
while (row < m_toprow + m_windowrows/2) {
int nsize = m_toprow < vscrollsize() ? m_toprow : vscrollsize();
m_toprow -= nsize;
if (m_toprow <= 0) {
m_toprow = 0;
break;
}
}
}
SetCaretPosition();
SetScrollPosition(SB_VERT, m_toprow);
Invalidate(false);
}
////////////////////////////////////////////////
// caret movement functions
void CEditorView::CaretDown()
{
if (m_currentrow + 1 < GetDocument()->linecount()) {
m_currentrow++;
AdjustScroll();
SetCaretPosition(false, true);
}
}
void CEditorView::CaretUp()
{
if (m_currentrow > 0) {
--m_currentrow;
AdjustScroll();
SetCaretPosition(false, true);
}
}
void CEditorView::CaretRight()
{
const std::string& str = GetDocument()->textline(m_currentrow);
if (m_currentcolumn == str.length() && m_currentrow + 1 < GetDocument()->linecount()) {
m_currentcolumn = 0;
m_currentrow++;
if (m_leftcolumn != 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -