📄 bcgpeditctrl.cpp
字号:
}
if (nIdx == -1)
{
return -1;
}
return nIdx++;
}
//***************************************************************************************
int CBCGPEditCtrl::GetRowTextStart (int nRowOffset, BOOL bSkipHidden) const
{
if (nRowOffset == -1)
{
return 0;
}
if (nRowOffset >= m_strBuffer.GetLength ())
{
return m_strBuffer.GetLength () - 1;
}
for (int i = nRowOffset; i < m_strBuffer.GetLength (); i++)
{
if (bSkipHidden && FindCollapsedBlock (i) != NULL)
{
break;
}
if (m_strBuffer [i] == g_chEOL)
{
break;
}
if (m_strNonSelectableChars.Find (m_strBuffer [i]) == -1)
{
break;
}
}
return i;
}
//***************************************************************************************
int CBCGPEditCtrl::GetRowStartByOffset (int nOffset, BOOL bSkipHidden) const
{
BOOL bFound = FALSE;
if (nOffset > m_strBuffer.GetLength ())
{
nOffset = m_strBuffer.GetLength ();
}
for (int i = nOffset - 1; i >= 0; i--)
{
if (m_strBuffer [i] == _T('\n'))
{
if (!bSkipHidden || FindCollapsedBlock (i) == NULL)
{
bFound = TRUE;
break;
}
}
}
if (!bFound)
{
return 0;
}
return i + 1;
}
//***************************************************************************************
int CBCGPEditCtrl::GetRowEndByOffset (int nOffset, BOOL bSkipHidden) const
{
int nIdx = m_strBuffer.Find (g_chEOL, nOffset);
while (nIdx != -1 && bSkipHidden && FindCollapsedBlock (nIdx) != NULL) // skip hidden text
{
nIdx = m_strBuffer.Find (g_chEOL, nIdx + 1);
}
if (nIdx == -1)
{
nIdx = m_strBuffer.GetLength () - 1;
}
return nIdx;
}
//**************************************************************************************
int CBCGPEditCtrl::GetNumOfCharsInText (const CString& strText, TCHAR ch)
{
int nNumChars = 0;
for (int iIdx = 0; iIdx != -1; iIdx++)
{
iIdx = strText.Find (ch, iIdx);
if (iIdx != -1)
{
nNumChars++;
}
else
{
break;
}
}
return nNumChars;
}
//***************************************************************************************
int CBCGPEditCtrl::GetNumOfCharsInText (int nStart, int nEnd, TCHAR ch, BOOL bSkipHidden) const
{
ASSERT (nStart >= 0);
ASSERT (nEnd < m_strBuffer.GetLength ());
if (nStart > nEnd)
{
return 0;
}
int nNumChars = 0;
for (int iIdx = nStart; iIdx != -1 && iIdx <= nEnd; iIdx++)
{
iIdx = m_strBuffer.Find (ch, iIdx);
if (iIdx != -1 && iIdx <= nEnd)
{
if (!bSkipHidden || FindCollapsedBlock (iIdx) == NULL)
{
nNumChars++;
}
}
else
{
break;
}
}
return nNumChars;
}
//***************************************************************************************
BOOL CBCGPEditCtrl::InsertChar (TCHAR nChar, BOOL bRedraw)
{
ASSERT_VALID (this);
ASSERT (m_nCurrOffset <= m_strBuffer.GetLength ());
CString strChar (nChar);
if (!OnBeforeTextInserted (strChar, m_nCurrOffset))
{
return FALSE;
}
if (nChar == _T('\n'))
{
if (GetOverrideMode ())
{
Home ();
return Down ();
}
return InsertNewLine (TRUE);
}
int nCurrOffset = m_nCurrOffset;
int nRowEndOffset = GetRowEndByOffset (m_nCurrOffset, FALSE);
int nRowLen = m_bKeepTabs ? GetNumOfColumnsInRowByOffset (m_nCurrOffset, nRowEndOffset, FALSE) :
nRowEndOffset - GetRowStartByOffset (m_nCurrOffset, FALSE);
if (nRowLen >= m_nMaxScrollWidth - 1)
{
HideCaret ();
InsertNewLine (TRUE);
if (nRowEndOffset != nCurrOffset)
{
SetCaret (nCurrOffset);
}
ShowCaret ();
}
BOOL bForceInsertMode = !GetOverrideMode () ||
((m_nCurrOffset == m_strBuffer.GetLength () ||
m_strBuffer.GetAt (m_nCurrOffset) == g_chEOL)) && GetOverrideMode ();
AddUndoAction (nChar, g_dwUATInsertData, m_nCurrOffset, bForceInsertMode);
BOOL bAtColorBlock = IsOffsetAtColorBlock (m_nCurrOffset);
if (GetOverrideMode () && !m_strBuffer.IsEmpty () &&
m_nCurrOffset < m_strBuffer.GetLength () &&
m_strBuffer.GetAt (m_nCurrOffset) != g_chEOL)
{
m_strBuffer.SetAt (m_nCurrOffset, nChar);
}
else
{
m_strBuffer.Insert (m_nCurrOffset, nChar);
}
UpdateOffsetRelatedData (m_nCurrOffset, m_nCurrOffset + 1);
OnUpdateAutoOutlining (m_nCurrOffset, 1, FALSE);
OnAfterTextChanged (m_nCurrOffset, CString (nChar), TRUE);
UpdateScrollBars ();
if (bRedraw)
{
if (IsOffsetAtColorBlock (m_nCurrOffset) || bAtColorBlock)
{
RedrawWindow (m_rectText);
}
else
{
RedrawRestOfLine (m_nCurrOffset);
}
}
Right ();
// IntelliSense char update ...
CString strIntelliSense;
if (!m_bIntelliSenseUpdate &&
IntelliSenseCharUpdate(m_strBuffer, m_nCurrOffset, nChar, strIntelliSense))
{
Sleep(100);
m_nCurrOffset--;
OnDelete(TRUE,TRUE);
if (strIntelliSense.IsEmpty())
{
ASSERT(FALSE);
}
else
{
m_bIntelliSenseUpdate = TRUE;
try
{
InsertText(strIntelliSense.GetBuffer(0), m_nCurrOffset, bRedraw);
}
catch (...)
{
ASSERT(FALSE);
}
m_bIntelliSenseUpdate = FALSE;
}
}
return TRUE;
}
//**************************************************************************************
BOOL CBCGPEditCtrl::InsertText (LPCTSTR lpszText, int nInsertFrom, BOOL bRedraw,
BOOL bSuppressUndo, BOOL bUpdateLineData,
BOOL bForceNextUndo, BOOL bAlwaysAtEnd)
{
ASSERT_VALID (this);
ASSERT (lpszText != NULL);
if (nInsertFrom >= 0)
{
nInsertFrom = min (nInsertFrom, m_strBuffer.GetLength ());
}
else
{
nInsertFrom = m_nCurrOffset;
}
CString strText = lpszText;
if (ProcessTextBeforeInsert (strText))
{
int nInsertedTextLength = strText.GetLength ();
int nCurrRowStartOffset = GetRowStartByOffset (m_nCurrOffset, FALSE);
if (m_nCurrOffset - nCurrRowStartOffset + nInsertedTextLength >= m_nMaxScrollWidth &&
m_nCurrOffset != 0 && !m_strBuffer.IsEmpty () &&
m_nCurrOffset != nCurrRowStartOffset &&
m_nCurrOffset < m_strBuffer.GetLength () - 1 &&
(m_strBuffer [m_nCurrOffset + 1] != g_chEOL ||
m_strBuffer [m_nCurrOffset] != g_chEOL) &&
!bAlwaysAtEnd)
{
OnFailedOperation (0x1000000 | 0x10000000);
strText.Insert (0, g_chEOL);
}
if (m_nCurrOffset >= m_strBuffer.GetLength () - 1 &&
m_nCurrOffset != nCurrRowStartOffset && !bAlwaysAtEnd)
{
OnFailedOperation (0x1000000 | 0x10000000);
strText.Insert (0, g_chEOL);
}
if (!OnBeforeTextInserted (strText, nInsertFrom))
{
return FALSE;
}
OnInsertTextToBuffer (nInsertFrom, strText, bUpdateLineData);
m_strBuffer.Insert (nInsertFrom, strText);
UpdateOffsetRelatedData (nInsertFrom, nInsertFrom + strText.GetLength ());
OnUpdateAutoOutlining (nInsertFrom, strText.GetLength (), FALSE);
int nRowEndOffset = GetRowEndByOffset (m_nCurrOffset + nInsertedTextLength, FALSE);
int nRowStartOffset = GetRowStartByOffset (m_nCurrOffset + nInsertedTextLength, FALSE);
int nRowLen = nRowEndOffset - nRowStartOffset;
if (bSuppressUndo)
{
EmptyUndoList ();
}
else
{
AddUndoAction (strText, g_dwUATInsertData, nInsertFrom, TRUE,
bForceNextUndo || nRowLen >= m_nMaxScrollWidth);
}
if (nRowLen >= m_nMaxScrollWidth)
{
InsertNewLine (FALSE, bForceNextUndo,
nRowStartOffset + m_nMaxScrollWidth - 1, FALSE);
}
UpdateScrollBars ();
SetCaret (nInsertFrom + strText.GetLength (), TRUE, bRedraw);
if (bRedraw)
{
RedrawWindow ();
}
OnAfterTextChanged (nInsertFrom, strText, TRUE);
return TRUE;
}
return FALSE;
}
//**************************************************************************************
BOOL CBCGPEditCtrl::InsertTextAsBlock (LPCTSTR lpszText, int nInsertFrom,
BOOL bRedraw, BOOL bSuppressUndo,
BOOL bUpdateLineData, BOOL bForceNextUndo)
{
if (nInsertFrom >= 0)
{
nInsertFrom = min (nInsertFrom, m_strBuffer.GetLength ());
}
else
{
nInsertFrom = m_nCurrOffset;
}
int nRowStartOffset = GetRowStartByOffset (nInsertFrom, TRUE);
int nRowEndOffset = GetRowEndByOffset (nInsertFrom, TRUE);
if (nRowEndOffset - nRowStartOffset < 2)
{
return InsertText (lpszText, nInsertFrom, bRedraw, bSuppressUndo, bUpdateLineData, bForceNextUndo);
}
CString strText = lpszText;
if (strText.IsEmpty ())
{
return TRUE;
}
int nStartColumn = GetColumnFromOffset (nInsertFrom, TRUE);
bool bAddedLines = false;
for (int nTextRowOffset = 0; nTextRowOffset < strText.GetLength ();)
{
int nNextRowOffset = strText.Find (g_chEOL, nTextRowOffset);
if (nNextRowOffset == -1)
{
nNextRowOffset = strText.GetLength ();
}
CString strSubRow = strText.Mid (nTextRowOffset, nNextRowOffset - nTextRowOffset);
if (nRowEndOffset >= m_strBuffer.GetLength ())
{
m_strBuffer += strSubRow;
m_nTotalLines++;
bAddedLines = true;
continue;
}
strSubRow.Remove (g_chEOL);
int nInsertOffset = GetOffsetOfColumnInRow (nStartColumn, nRowEndOffset, TRUE, TRUE);
nRowEndOffset += strSubRow.GetLength () + 1;
nInsertOffset = min (nRowEndOffset - 1, nInsertOffset);
if (OnBeforeTextInserted (strSubRow, nInsertOffset))
{
m_strBuffer.Insert (nInsertOffset, strSubRow);
UpdateOffsetRelatedData (nInsertOffset, nInsertOffset + strSubRow.GetLength ());
OnUpdateAutoOutlining (nInsertFrom, strSubRow.GetLength (), FALSE);
OnAfterTextChanged (nInsertOffset, strSubRow, TRUE);
}
nRowEndOffset = GetRowEndByOffset (nRowEndOffset, TRUE);
nTextRowOffset = nNextRowOffset + 1;
}
if (bAddedLines)
{
UpdateScrollBars ();
}
if (bRedraw)
{
RedrawWindow ();
}
return TRUE;
}
//**************************************************************************************
BOOL CBCGPEditCtrl::ProcessTextBeforeInsert (CString& strText)
{
strText.Remove (_T('\r'));
if (!m_bKeepTabs)
{
CString strTab (_T (' '), m_nTabSize);
strText.Replace (_T("\t"), strTab);
}
// truncate strings that too long
for (int i = 0, nCount = 0; i < strText.GetLength (); i++)
{
strText [i] == g_chEOL ? nCount = 0 : nCount++;
if (nCount == m_nMaxScrollWidth)
{
strText.Insert (i, g_chEOL);
nCount = 0;
}
}
return TRUE;
}
//**************************************************************************************
BOOL CBCGPEditCtrl::InsertNewLine (BOOL bRedraw, BOOL bForceNextUndo, int nOffset,
BOOL bSetCaret)
{
if (nOffset == -1)
{
nOffset = m_nCurrOffset;
}
int nRowNum = RowFromOffset (nOffset);
int nRowStartOffset = GetRowStartByOffset (nOffset, TRUE);
BOOL bLineStart = m_nCurrOffset == nRowStartOffset;
if (!OnInsertNewLine (bForceNextUndo, nOffset, bSetCaret))
{
return FALSE;
}
if (bLineStart)
{
// the new line is inserted at the beginning of the current line
// the current line with all markesr should be moved down
UpdateLineRelatedData (nRowNum, 1);
}
else
{
// the new line is inserted at the middle of the current line
// the rest of the current line with all markers starting
// from the next line should be moved down
UpdateLineRelatedData (nRowNum + 1, 1);
}
UpdateScrollBars ();
m_bIsModified = TRUE;
if (bRedraw)
{
RedrawWindow ();
}
return TRUE;
}
//***************************************************************************************
BOOL CBCGPEditCtrl::OnInsertNewLine (BOOL bForceNextUndo, int nOffset,
BOOL bSetCaret)
{
if (nOffset == -1)
{
nOffset = m_nCurrOffset;
}
int nCurrRowStart = GetRowStartByOffset (nOffset, TRUE);
int nCurrRowTextStart = GetRowTextStart (nCurrRowStart, TRUE);
CString strToInsert (g_chEOL);
if (m_bDefaultIndent && nCurrRowTextStart > nCurrRowStart)
{
int nCount = min (nOffset - nCurrRowStart, nCurrRowTextStart - nCurrRowStart);
CString strRowStart = m_strBuffer.Mid (nCurrRowStart, nCount);
strToInsert += strRowStart;
}
if (!OnBeforeTextInserted (strToInsert, nOffset))
{
return FALSE;
}
AddUndoAction (strToInsert, g_dwUATInsertData, nOffset, FALSE, bForceNextUndo);
m_strBuffer.Insert (nOffset, strToInsert);
UpdateOffsetRelatedData (nOffset, nOffset + strToInsert.GetLength ());
OnUpdateAutoOutlining (nOffset, strToInsert.GetLength (), FALSE);
OnAfterTextChanged (nOffset, strToInsert, TRUE);
if (bSetCaret)
{
if (m_bDefaultIndent)
{
SetCaret (nOffset + strToInsert.GetLength ());
}
else
{
Down ();
Home ();
}
}
m_nTotalLines++;
return TRUE;
}
//***************************************************************************************
BOOL CBCGPEditCtrl::InsertTab (BOOL bRedraw)
{
CString strTab;
int nInsertOffset = m_nCurrOffset;
int nRowEndOffset = GetRowEndByOffset (m_nCurrOffset, TRUE);
int nRowLen = m_bKeepTabs ? GetNumOfColumnsInRowByOffset (m_nCurrOffset, nRowEndOffset, TRUE) :
nRowEndOffset - GetRowStartByOffset (m_nCurrOffset, TRUE);
if (nRowLen + m_nIndentSize > m_nMaxScrollWidth - 1)
{
OnFailedOperation (g_dwOpInsTab | g_dwOpReason
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -