📄 editorview.cpp
字号:
}
CView::OnLButtonDblClk(nFlags, point);
}
void CEditorView::OnLButtonDown(UINT nFlags, CPoint point)
{
if (!m_recording) {
CPoint pt = ScreenToCharCoordinates(point);
m_currentrow = pt.y;
m_currentcolumn = pt.x;
SetCaretPosition();
ReleaseCapture();
if (m_pEditorSelection->IsItemInSelection(ViewIndex(this, m_currentrow, m_currentcolumn))) {
SetCapture();
m_hOldCursor = SetCursor(m_ctrldown ? m_hCopyCursor : m_hMoveCursor);
m_dragging = true;
m_pEditorSelection->SaveSelection();
return;
}
m_pEditorSelection->UnmarkSelection();
m_mousemarking = true;
m_pEditorSelection->SetMarking(ViewIndex(this, m_currentrow, m_currentcolumn));
KillTimer(0);
SetCapture();
}
CView::OnLButtonDown(nFlags, point);
}
void CEditorView::OnLButtonUp(UINT nFlags, CPoint point)
{
KillTimer(0);
if (!m_recording) {
if (m_dragging) {
ViewIndex cvndx(this, m_currentrow, m_currentcolumn);
if (!m_pEditorSelection->IsItemInSelection(cvndx)) {
// ---- build a vector from the selection
std::string str;
SelectionToString(str);
std::vector<std::string> strs;
StringToVector(strs, str.c_str());
if (!m_ctrldown)
// ---- moving, delete the marked selection shifting instead of resetting the caret
DeleteSelection(false);
// ---- drop the marked selection into the document
InsertStringsIntoDocument(strs, false);
if (m_ctrldown)
// ---- copying, reinvert the marked selection display
m_pEditorSelection->RestoreSelection();
Invalidate(false);
SetCursor(m_hOldCursor);
}
else
m_pEditorSelection->UnmarkSelection();
m_dragging = false;
ReleaseCapture();
}
else if (m_mousemarking) {
m_mousemarking = false;
m_pEditorSelection->StopMarking();
ReleaseCapture();
}
}
CView::OnLButtonUp(nFlags, point);
}
void CEditorView::OnMouseMove(UINT nFlags, CPoint point)
{
if (!m_recording && (m_mousemarking || m_dragging)) {
m_ScrollPos = point;
if (point.y < 0) {
CaretUp();
SetTimer(0, 100, 0);
return;
}
if (point.y > m_windowrows) {
CaretDown();
SetTimer(0, 100, 0);
return;
}
CPoint pt = ScreenToCharCoordinates(point);
if (pt.x >= 0 && pt.x < m_windowcolumns) {
m_currentrow = pt.y;
m_currentcolumn = pt.x;
SetCaretPosition();
if (m_mousemarking)
m_pEditorSelection->ExtendSelection(ViewIndex(this, m_currentrow, m_currentcolumn));
}
}
}
void CEditorView::OnTimer(UINT nIDEvent)
{
if (nIDEvent == 0) {
KillTimer(0);
OnMouseMove(0, m_ScrollPos);
}
CView::OnTimer(nIDEvent);
}
////////////////////////////////////////////////////
// keyboard functions
void CEditorView::TestSelection()
{
if (!m_shiftdown && IsSelectionMarked())
m_pEditorSelection->UnmarkSelection();
}
void CEditorView::TestMarking()
{
if (m_shiftdown)
m_pEditorSelection->SetMarking(ViewIndex(this, m_currentrow, m_currentcolumn));
}
void CEditorView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if (m_recording)
RecordCommand(new KeyDown(this, nChar));
if (ExtendEditor(nChar))
return;
switch (nChar) {
case VK_TAB:
InsertTab();
return;
case VK_BACK:
if (m_currentrow || m_currentcolumn) {
CaretLeft();
DeleteCharacter();
}
return;
case VK_RETURN:
SplitLine();
CaretRight();
return;
case VK_DELETE:
if (m_ctrldown)
DeleteWord();
else
DeleteCharacter();
return;
default:
break;
}
switch (nChar) {
case VK_CONTROL:
m_ctrldown = true;
return;
case VK_SHIFT:
m_shiftdown = true;
return;
case VK_DOWN:
TestSelection();
if (m_ctrldown)
ScrollUp();
else {
TestMarking();
CaretDown();
}
return;
case VK_UP:
TestSelection();
if (m_ctrldown)
ScrollDown();
else {
TestMarking();
CaretUp();
}
return;
case VK_RIGHT:
TestSelection();
TestMarking();
m_ctrldown ? WordRight() : CaretRight();
return;
case VK_LEFT:
TestSelection();
TestMarking();
m_ctrldown ? WordLeft() : CaretLeft();
return;
case VK_NEXT:
TestSelection();
if (!m_ctrldown) {
TestMarking();
PageDown();
m_currentrow += m_windowrows / m_fontheight;
SetCaretPosition(false, true);
}
return;
case VK_PRIOR:
TestSelection();
if (!m_ctrldown){
TestMarking();
PageUp();
m_currentrow -= m_windowrows / m_fontheight;
SetCaretPosition(false, true);
}
return;
case VK_END:
TestSelection();
TestMarking();
if (m_ctrldown)
PageEnd();
else
LineEnd();
return;
case VK_HOME:
TestSelection();
TestMarking();
if (m_ctrldown)
PageHome();
else
LineHome();
return;
default:
break;
}
}
void CEditorView::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if (m_recording && (nChar == VK_CONTROL || nChar == VK_SHIFT))
RecordCommand(new KeyUp(this, nChar));
if (nChar == VK_CONTROL)
m_ctrldown = false;
else if (nChar == VK_SHIFT)
m_shiftdown = false;
}
void CEditorView::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if (isprint(nChar)) {
if (m_recording)
RecordCommand(new Char(this, nChar));
if (!ExtendEditor(nChar)) {
InsertCharacter(nChar);
CaretRight();
}
}
}
////////////////////////////////////////////////////////
// macro functions
void CEditorView::DeleteMacros()
{
std::vector<MacroCommand*>::iterator iter = m_macrocommands.begin();
while (iter != m_macrocommands.end())
delete *(iter++);
m_macrocommands.clear();
}
void CEditorView::OnRecord()
{
m_recording = true;
CMenu* pMenu = ((CMainFrame*)theApp.m_pMainWnd)->GetMenu();
assert(pMenu != 0);
pMenu->ModifyMenu(ID_RECORD, MF_BYCOMMAND | MF_STRING, ID_STOPRECORD, "&Stop\tAlt+S");
DeleteMacros();
SetCursor(m_hRecordCursor);
}
void CEditorView::OnStopRecord()
{
m_recording = false;
CMenu* pMenu = ((CMainFrame*)theApp.m_pMainWnd)->GetMenu();
assert(pMenu != 0);
pMenu->ModifyMenu(ID_STOPRECORD, MF_BYCOMMAND | MF_STRING, ID_RECORD, "&Record\tAlt+R");
SetCursor(m_hArrowCursor);
}
void CEditorView::RecordCommand(MacroCommand* pCmd)
{
m_macrocommands.push_back(pCmd);
}
void CEditorView::OnPlayback()
{
std::vector<MacroCommand*>::iterator iter = m_macrocommands.begin();
while (iter != m_macrocommands.end()) {
(*iter)->PlayBack();
iter++;
}
}
void CEditorView::OnUpdatePlayback(CCmdUI* pCmdUI)
{
pCmdUI->Enable(!m_recording && !m_macrocommands.empty());
}
void CEditorView::OnUpdateRecord(CCmdUI* pCmdUI)
{
pCmdUI->Enable(!m_recording);
}
void CEditorView::OnUpdateStopRecord(CCmdUI* pCmdUI)
{
pCmdUI->Enable(m_recording);
}
////////////////////////////////////////////////////////
// clipboard functions
void CEditorView::OnUpdateEditCut(CCmdUI* pCmdUI)
{
pCmdUI->Enable(IsSelectionMarked());
}
//void CEditorView::OnUpdateEditCopy(CCmdUI* pCmdUI)
//{
// pCmdUI->Enable(IsSelectionMarked());
//}
void CEditorView::OnUpdateEditPaste(CCmdUI* pCmdUI)
{
pCmdUI->Enable(IsClipboardFormatAvailable(CF_TEXT));
}
void CEditorView::OnUpdateEditClear(CCmdUI* pCmdUI)
{
pCmdUI->Enable(!IsRecording() && IsSelectionMarked());
}
void CEditorView::OnEditCut()
{
OnEditCopy();
OnEditClear();
}
void CEditorView::OnEditClear()
{
DeleteSelection();
}
void CEditorView::OnEditSelectAll()
{
m_pEditorSelection->UnmarkSelection();
PageHome();
m_pEditorSelection->SetMarking(ViewIndex(this, 0, 0));
int endrow = GetDocument()->linecount() - 1;
int endcol = GetDocument()->textline(endrow).length();
m_pEditorSelection->ExtendSelection(ViewIndex(this, endrow, endcol));
}
// ------ functions to support view contexts for undo/redo
void CEditorView::GetCurrentPosition(unsigned int& toprow, unsigned int& leftcolumn, unsigned int& row, unsigned int& column) const
{
toprow = m_toprow;
leftcolumn = m_leftcolumn;
row = m_currentrow;
column = m_currentcolumn;
}
void CEditorView::SetCurrentPosition(unsigned int toprow, unsigned int leftcolumn, unsigned int row, unsigned int column)
{
if (m_leftcolumn != leftcolumn || m_toprow != toprow)
Invalidate(false); // changing scroll position
m_toprow = toprow;
m_leftcolumn = leftcolumn;
m_currentrow = row;
m_currentcolumn = column;
SetScrollPosition(SB_VERT, m_toprow);
SetCaretPosition();
AdjustScroll();
}
// --- copy the text selection to one string, collapsing tab expansions
// and inserting \r\n between lines
// Used by cut, copy and drop operations
void CEditorView::SelectionToString(std::string& str)
{
ViewIndex begin, end;
m_pEditorSelection->GetSelectionMarkers(begin, end);
std::string strline = GetDocument()->textline(begin.row);
if (begin.row == end.row) {
// --- the selection is all on one line
str = strline.substr(begin.column, end.column - begin.column);
CEditorDoc::entab(str);
}
else {
str = strline.substr(begin.column, strline.length() - begin.column) + "\r\n";
CEditorDoc::entab(str);
while (++begin.row != end.row) {
strline = GetDocument()->textline(begin.row);
CEditorDoc::entab(strline);
str += strline + "\r\n";
}
if (end.row != GetDocument()->linecount()) {
strline = GetDocument()->textline(end.row);
CEditorDoc::entab(strline);
str += strline.substr(0, end.column);
if (end.column == 0)
str += "\r\n";
}
}
}
// --- build a vector of strings from a null-terminated string with "\r\n" separators
// Used by paste and drop operations
void CEditorView::StringToVector(std::vector<std::string>& strs, const char* cp)
{
std::string str;
while (*cp) {
str += *cp;
if (*cp == '\n') {
strs.push_back(str.substr(0, str.length()-2));
str.erase();
}
cp++;
}
if (str.length() > 0)
strs.push_back(str);
}
// --- insert a vector of text line strings into the document at the current insertion point,
// expanding tabs
// Used by paste and drop operations
void CEditorView::InsertStringsIntoDocument(const std::vector<std::string>& strs, bool bterminate)
{
if (strs.size() > 0) {
m_buildcomments = true;
const std::string& str = GetDocument()->textline(m_currentrow);
std::string first = str.substr(0, m_currentcolumn);
std::string last = str.substr(m_currentcolumn, str.length() - m_currentcolumn);
std::string mid = *strs.begin();
if (strs.size() == 1) {
// --- only one text line in the vector
int ccol = first.length();
CEditorDoc::detab(mid);
ccol += mid.length();
CEditorDoc::entab(mid);
CEditorDoc::entab(first);
CEditorDoc::entab(last);
std::string str(first+mid+last);
CEditorDoc::detab(str);
GetDocument()->replaceline(m_currentrow, str, bterminate);
m_currentcolumn = ccol;
}
else {
// ---- process the first line from the vector
CEditorDoc::entab(first);
std::string str(first+mid);
CEditorDoc::detab(str);
GetDocument()->replaceline(m_currentrow, str, bterminate);
int inserter = m_currentrow + 1;
// ---- process the middle lines from the vector
if (strs.size() > 2) {
std::vector<std::string>::const_iterator iter;
for (iter = strs.begin() + 1; iter != strs.end()-1; iter++) {
std::string mstr = *iter;
CEditorDoc::detab(mstr);
GetDocument()->insertline(inserter++, mstr, false);
}
}
// ---- process the last line from the vector
std::string lstr = *(strs.end()-1);
CEditorDoc::detab(lstr);
unsigned int ccol = lstr.length();
CEditorDoc::entab(lstr);
str = lstr + last;
CEditorDoc::detab(str);
if (inserter >= GetDocument()->linecount())
GetDocument()->appendline(str, false);
else
GetDocument()->insertline(inserter, str, false);
m_currentcolumn = ccol;
m_currentrow = inserter;
}
}
}
void CEditorView::StringToClipboard(const std::string& str)
{
HGLOBAL hGlobalMemory = GlobalAlloc(GHND, str.length() + 1);
if (hGlobalMemory != 0) {
char* pGlobalMemory = (char*) GlobalLock(hGlobalMemory);
if (pGlobalMemory != 0) {
int len = str.length();
const char* cp = str.c_str();
while (len--)
*pGlobalMemory++ = *cp++;
}
GlobalUnlock(hGlobalMemory);
OpenClipboard();
EmptyClipboard();
SetClipboardData(CF_TEXT, hGlobalMemory);
CloseClipboard();
}
}
void CEditorView::OnEditCopy()
{
std::string str;
SelectionToString(str);
if (str.empty())
str = GetDocument()->textline(m_currentrow);
StringToClipboard(str);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -