int CXTPSyntaxEditCtrl::CalculateVisibleRow(int nStartDocumentRow, int nDocumentRow){
return max(CalculateVisibleRow_(nStartDocumentRow, nDocumentRow), 1);
}
int CXTPSyntaxEditCtrl::CalculateVisibleRow_(int nStartDocumentRow, int nDocumentRow)
{
int nVisRow = nDocumentRow - nStartDocumentRow + 1;
int nNextCollapsedRow = nStartDocumentRow - 1;
const int nRowCount = GetRowCount();
POSITION pos = GetLineMarksManager()->FindNextLineMark(nNextCollapsedRow, xtpEditLMT_Collapsed);
while (pos != NULL)
{
XTP_EDIT_LMDATA* pData = GetLineMarksManager()->GetNextLineMark(pos, xtpEditLMT_Collapsed);
if (pData && pData->m_nRow >= nNextCollapsedRow) // mark should be not within previous collapsed block
{
if (pData->m_nRow >= nDocumentRow) // finish if mark is greater then row to calculate for
break;
XTP_EDIT_COLLAPSEDBLOCK* pCoDBlk = (XTP_EDIT_COLLAPSEDBLOCK*)pData->m_Param.GetPtr();
if (!pCoDBlk)
continue;
int nBlkEnd = min(nRowCount, pCoDBlk->collBlock.lcEnd.nLine);
if (nBlkEnd > nDocumentRow)
nBlkEnd = nDocumentRow; // DocumentRow in invisible(collapsed) block
int nHiddenRows = nBlkEnd - pCoDBlk->collBlock.lcStart.nLine;
nVisRow -= nHiddenRows;
nNextCollapsedRow = pData->m_nRow + nHiddenRows;
}
}
return nVisRow;
}
void CXTPSyntaxEditCtrl::PrevBookmark()
{
CXTPSyntaxEditLineMarksManager* pMgr = GetLineMarksManager();
if (!pMgr)
{
ASSERT(FALSE);
return;
}
int nRow = GetCurRow();
int nVisRow = CalculateVisibleRow_(m_nTopRow, GetCurrentDocumentRow());
// move up to the prev bookmark before the current collapsed block area
int nPrevRow = nRow;
do {
pMgr->FindPrevLineMark(--nPrevRow, xtpEditLMT_Bookmark);
} while (nPrevRow > 0 && CalculateVisibleRow_(m_nTopRow, nPrevRow) == nVisRow);
if (nPrevRow < 0)
{
POSITION posLast = pMgr->GetLastLineMark(xtpEditLMT_Bookmark);
XTP_EDIT_LMDATA* pData = pMgr->GetLineMarkAt(posLast, xtpEditLMT_Bookmark);
nPrevRow = pData ? pData->m_nRow : -1;
}
if (CalculateVisibleRow_(m_nTopRow, nPrevRow) == nVisRow)
{
nPrevRow = -1;
}
if (nPrevRow >= 0)
{
SetCurPos(nPrevRow, 1);
Invalidate(FALSE);
}
}
void CXTPSyntaxEditCtrl::NextBookmark()
{
CXTPSyntaxEditLineMarksManager* pMgr = GetLineMarksManager();
if (!pMgr)
{
ASSERT(FALSE);
return;
}
int nRow = GetCurRow();
int nVisRow = CalculateVisibleRow_(m_nTopRow, GetCurrentDocumentRow());
// move down to the next bookmark after the current collapsed block area
int nNextRow = nRow;
do {
pMgr->FindNextLineMark(++nNextRow, xtpEditLMT_Bookmark);
} while (nNextRow > 0 && CalculateVisibleRow_(m_nTopRow, nNextRow) == nVisRow);
if (nNextRow < 0)
{
// find first line mark
POSITION posFirst = pMgr->GetFirstLineMark(xtpEditLMT_Bookmark);
XTP_EDIT_LMDATA* pData = pMgr->GetNextLineMark(posFirst, xtpEditLMT_Bookmark);
nNextRow = pData ? pData->m_nRow : -1;
}
if (CalculateVisibleRow_(m_nTopRow, nNextRow) == nVisRow)
{
nNextRow = -1;
}
if (nNextRow >= 0)
{
SetCurPos(nNextRow, 1);
Invalidate(FALSE);
}
}