📄 editorview.cpp
字号:
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 + -