void CCrystalEditView::OnEditTab() { if (! QueryEditable() || m_pTextBuffer == NULL) return; BOOL bTabify = FALSE; CPoint ptSelStart, ptSelEnd; if (IsSelection()) { GetSelection(ptSelStart, ptSelEnd); bTabify = ptSelStart.y != ptSelEnd.y; } if (bTabify) { m_pTextBuffer->BeginUndoGroup(); int nStartLine = ptSelStart.y; int nEndLine = ptSelEnd.y; ptSelStart.x = 0; if (ptSelEnd.x > 0) { if (ptSelEnd.y == GetLineCount() - 1) { ptSelEnd.x = GetLineLength(ptSelEnd.y); } else { ptSelEnd.x = 0; ptSelEnd.y ++; } } else nEndLine --; SetSelection(ptSelStart, ptSelEnd); SetCursorPos(ptSelEnd); EnsureVisible(ptSelEnd); // Shift selection to right m_bHorzScrollBarLocked = TRUE; static const TCHAR pszText[] = _T("\t"); for (int L = nStartLine; L <= nEndLine; L ++) { int x, y; m_pTextBuffer->InsertText(this, L, 0, pszText, y, x, CE_ACTION_INDENT); // [JRT] } m_bHorzScrollBarLocked = FALSE; RecalcHorzScrollBar(); m_pTextBuffer->FlushUndoGroup(this); return; } if (m_bOvrMode) { CPoint ptCursorPos = GetCursorPos(); ASSERT_VALIDTEXTPOS(ptCursorPos); int nLineLength = GetLineLength(ptCursorPos.y); LPCTSTR pszLineChars = GetLineChars(ptCursorPos.y); if (ptCursorPos.x < nLineLength) { int nTabSize = GetTabSize(); int nChars = nTabSize - CalculateActualOffset(ptCursorPos.y, ptCursorPos.x) % nTabSize; ASSERT(nChars > 0 && nChars <= nTabSize); while (nChars > 0) { if (ptCursorPos.x == nLineLength) break; if (pszLineChars[ptCursorPos.x] == _T('\t')) { ptCursorPos.x ++; break; } ptCursorPos.x ++; nChars --; } ASSERT(ptCursorPos.x <= nLineLength); ASSERT_VALIDTEXTPOS(ptCursorPos); SetSelection(ptCursorPos, ptCursorPos); SetAnchor(ptCursorPos); SetCursorPos(ptCursorPos); EnsureVisible(ptCursorPos); return; } } m_pTextBuffer->BeginUndoGroup(); DeleteCurrentSelection(); CPoint ptCursorPos = GetCursorPos(); ASSERT_VALIDTEXTPOS(ptCursorPos); static const TCHAR pszText[] = _T("\t"); int x, y; m_pTextBuffer->InsertText(this, ptCursorPos.y, ptCursorPos.x, pszText, y, x, CE_ACTION_TYPING); // [JRT] ptCursorPos.x = x; ptCursorPos.y = y; ASSERT_VALIDTEXTPOS(ptCursorPos); SetSelection(ptCursorPos, ptCursorPos); SetAnchor(ptCursorPos); SetCursorPos(ptCursorPos); EnsureVisible(ptCursorPos); m_pTextBuffer->FlushUndoGroup(this); }
void CCrystalEditView::OnEditUntab() { if (! QueryEditable() || m_pTextBuffer == NULL) return; BOOL bTabify = FALSE; CPoint ptSelStart, ptSelEnd; if (IsSelection()) { GetSelection(ptSelStart, ptSelEnd); bTabify = ptSelStart.y != ptSelEnd.y; } if (bTabify) { m_pTextBuffer->BeginUndoGroup(); CPoint ptSelStart, ptSelEnd; GetSelection(ptSelStart, ptSelEnd); int nStartLine = ptSelStart.y; int nEndLine = ptSelEnd.y; ptSelStart.x = 0; if (ptSelEnd.x > 0) { if (ptSelEnd.y == GetLineCount() - 1) { ptSelEnd.x = GetLineLength(ptSelEnd.y); } else { ptSelEnd.x = 0; ptSelEnd.y ++; } } else nEndLine --; SetSelection(ptSelStart, ptSelEnd); SetCursorPos(ptSelEnd); EnsureVisible(ptSelEnd); // Shift selection to left m_bHorzScrollBarLocked = TRUE; for (int L = nStartLine; L <= nEndLine; L ++) { int nLength = GetLineLength(L); if (nLength > 0) { LPCTSTR pszChars = GetLineChars(L); int nPos = 0, nOffset = 0; while (nPos < nLength) { if (pszChars[nPos] == _T(' ')) { nPos ++; if (++ nOffset >= GetTabSize()) break; } else { if (pszChars[nPos] == _T('\t')) nPos ++; break; } } if (nPos > 0) m_pTextBuffer->DeleteText(this, L, 0, L, nPos, CE_ACTION_INDENT); // [JRT] } } m_bHorzScrollBarLocked = FALSE; RecalcHorzScrollBar(); m_pTextBuffer->FlushUndoGroup(this); } else { CPoint ptCursorPos = GetCursorPos(); ASSERT_VALIDTEXTPOS(ptCursorPos); if (ptCursorPos.x > 0) { int nTabSize = GetTabSize(); int nOffset = CalculateActualOffset(ptCursorPos.y, ptCursorPos.x); int nNewOffset = nOffset / nTabSize * nTabSize; if (nOffset == nNewOffset && nNewOffset > 0) nNewOffset -= nTabSize; ASSERT(nNewOffset >= 0); LPCTSTR pszChars = GetLineChars(ptCursorPos.y); int nCurrentOffset = 0; int I = 0; while (nCurrentOffset < nNewOffset) { if (pszChars[I] == _T('\t')) nCurrentOffset = nCurrentOffset / nTabSize * nTabSize + nTabSize; else nCurrentOffset ++; I ++; } ASSERT(nCurrentOffset == nNewOffset); ptCursorPos.x = I; ASSERT_VALIDTEXTPOS(ptCursorPos); SetSelection(ptCursorPos, ptCursorPos); SetAnchor(ptCursorPos); SetCursorPos(ptCursorPos); EnsureVisible(ptCursorPos); } } }
void CEditWnd::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) { CTextWnd::OnKeyDown(nChar, nRepCnt, nFlags); if (!QueryEditable() || m_pTextBuffer == NULL) return; bool isShift = (GetKeyState(VK_SHIFT) & 0xF0) != 0; bool isCtrl = (GetKeyState(VK_CONTROL) & 0xF0) != 0; if (nChar == VK_TAB) { BOOL bTabify = FALSE; CPoint ptSelStart, ptSelEnd; if (IsSelection()) { GetSelection(ptSelStart, ptSelEnd); bTabify = ptSelStart.y != ptSelEnd.y; } if (bTabify) { m_pTextBuffer->BeginUndoGroup(); int nStartLine = ptSelStart.y; int nEndLine = ptSelEnd.y; ptSelStart.x = 0; if (ptSelEnd.x > 0) { if (ptSelEnd.y == GetLineCount() - 1) { ptSelEnd.x = GetLineLength(ptSelEnd.y); } else { ptSelEnd.x = 0; ptSelEnd.y ++; } } else nEndLine --; SetSelection(ptSelStart, ptSelEnd); SetCursorPos(ptSelEnd); EnsureVisible(ptSelEnd); // Shift selection to right m_bHorzScrollBarLocked = TRUE; //static const TCHAR pszText[] = _T("\t"); CString pszText; if (!m_bReplaceTabs) pszText = "\t"; else { CString tmp(' ', GetTabSize()); pszText = tmp; } for (int L = nStartLine; L <= nEndLine; L ++) { int x, y; m_pTextBuffer->InsertText(this, L, 0, pszText, y, x, CE_ACTION_INDENT); } m_bHorzScrollBarLocked = FALSE; RecalcHorzScrollBar(); m_pTextBuffer->FlushUndoGroup(this); } else { m_pTextBuffer->BeginUndoGroup(); DeleteCurrentSelection(); CPoint ptCursorPos = GetCursorPos(); ASSERT_VALIDTEXTPOS(ptCursorPos); CString pszText; if (!m_bReplaceTabs) pszText = "\t"; else { CString tmp(' ', GetTabSize()); pszText = tmp; } int x, y; m_pTextBuffer->InsertText(this, ptCursorPos.y, ptCursorPos.x, pszText, y, x, CE_ACTION_TYPING); ptCursorPos.x = x; ptCursorPos.y = y; ASSERT_VALIDTEXTPOS(ptCursorPos); SetSelection(ptCursorPos, ptCursorPos); SetAnchor(ptCursorPos); SetCursorPos(ptCursorPos); EnsureVisible(ptCursorPos); m_pTextBuffer->FlushUndoGroup(this); } } if (nChar == VK_BACK && !IsSelection()) { CPoint ptCursorPos = GetCursorPos(); if (ptCursorPos.y > 0 || (ptCursorPos.x > 0 && ptCursorPos.y == 0)) { CPoint ptCurrentCursorPos = ptCursorPos; bool bDeleted = false; if(ptCursorPos.x == 0) { ptCursorPos.y--; ptCursorPos.x = GetLineLength(ptCursorPos.y); bDeleted = true; } else { ptCursorPos.x--; bDeleted = true; } ASSERT_VALIDTEXTPOS(ptCursorPos); SetAnchor(ptCursorPos); SetSelection(ptCursorPos, ptCursorPos); SetCursorPos(ptCursorPos); EnsureVisible(ptCursorPos); if (bDeleted) m_pTextBuffer->DeleteText(this, ptCursorPos.y, ptCursorPos.x, ptCurrentCursorPos.y, ptCurrentCursorPos.x, CE_ACTION_BACKSPACE); } } if (nChar == VK_DELETE && !isShift) { CPoint ptSelStart, ptSelEnd; GetSelection(ptSelStart, ptSelEnd); if (ptSelStart == ptSelEnd) { if (ptSelEnd.x == GetLineLength(ptSelEnd.y)) { if (ptSelEnd.y == GetLineCount() - 1) return; ptSelEnd.y++; ptSelEnd.x = 0; if (GetLineLength(ptSelStart.y) != 0) { LPCSTR chars = GetLineChars(ptSelEnd.y); for (int j = 0; j < QUOTE_LENGTH && j < GetLineLength(ptSelEnd.y); j++) if (chars[j] == '>') ptSelEnd.x = j + 1; while (ptSelEnd.x < GetLineLength(ptSelEnd.y) && (chars[ptSelEnd.x] == ' ' || chars[ptSelEnd.x] == '\t')) ptSelEnd.x++; } } else ptSelEnd.x++; } CPoint ptCursorPos = ptSelStart; ASSERT_VALIDTEXTPOS(ptCursorPos); SetAnchor(ptCursorPos); SetSelection(ptCursorPos, ptCursorPos); SetCursorPos(ptCursorPos); EnsureVisible(ptCursorPos); m_pTextBuffer->DeleteText(this, ptSelStart.y, ptSelStart.x, ptSelEnd.y, ptSelEnd.x, CE_ACTION_DELETE); } if ((nChar == 'X' && isCtrl) || (nChar == VK_DELETE && isShift)) Cut(); if ((nChar == 'V' && isCtrl) || (nChar == VK_INSERT && isShift)) Paste(); if (nChar == 'Z' && isCtrl && isShift) Redo(); if (nChar == 'Z' && isCtrl && !isShift) Undo(); }