SynEdit: FoldedView, fix accessing out of range lines (due to wrong internal fTopViewPos). Introduced in 86abcd75d9

This commit is contained in:
Martin 2025-03-09 12:44:46 +01:00
parent 482124d17e
commit 847f6ab0e4

View File

@ -3429,40 +3429,48 @@ begin
CurFoldedBefore := node.FoldedBefore; CurFoldedBefore := node.FoldedBefore;
ViewIdx := ToIdx(fTopViewPos + CurFoldedBefore); ViewIdx := ToIdx(fTopViewPos + CurFoldedBefore);
TxtIdx := NextLines.DisplayView.ViewToTextIndexEx(ViewIdx, ViewRange); TxtIdx := NextLines.DisplayView.ViewToTextIndexEx(ViewIdx, ViewRange);
cnt := NextLines.Count;
// Prepare data for line one above fTopViewPos // Prepare data for line one above fTopViewPos
If ViewIdx > ViewRange.Top then begin if (TxtIdx >= cnt) or (TxtIdx < -1) then begin
// Need CurLine.... data for wrapped lines // Past end of Text
CurLineCapability := FFoldProvider.LineCapabilities[TxtIdx]; NewCapability := [];
CurLineClassifications := FFoldProvider.LineClassification[TxtIdx]; NewClassifications := [];
NewCapability := CurLineCapability;
NewClassifications := CurLineClassifications;
TmpRange := ViewRange;
TmpViewIdx := ViewIdx - 1;
end end
else begin else begin
TmpTxtIdx := TxtIdx - 1; If ViewIdx > ViewRange.Top then begin
if node.IsInFold then tmpnode := node.Prev // Need CurLine.... data for wrapped lines
else tmpnode := fFoldTree.LastPage; CurLineCapability := FFoldProvider.LineCapabilities[TxtIdx];
if tmpnode.IsInFold and (tmpnode.StartLine + tmpnode.MergedLineCount - 1 = ToPos(TmpTxtIdx)) CurLineClassifications := FFoldProvider.LineClassification[TxtIdx];
then TmpTxtIdx := TmpTxtIdx - node.MergedLineCount // Line before is in fold NewCapability := CurLineCapability;
else tmpnode.Init(nil, 0, 0); NewClassifications := CurLineClassifications;
NewCapability := FFoldProvider.LineCapabilities[TmpTxtIdx]; TmpRange := ViewRange;
NewClassifications := FFoldProvider.LineClassification[TmpTxtIdx]; TmpViewIdx := ViewIdx - 1;
if (tmpnode.IsInFold) then begin end
if tmpnode.IsHide then include(NewCapability, cfCollapsedHide) else begin
else include(NewCapability, cfCollapsedFold); TmpTxtIdx := TxtIdx - 1;
include(NewClassifications, tmpnode.Page._Classification); if node.IsInFold then tmpnode := node.Prev
else tmpnode := fFoldTree.LastPage;
if tmpnode.IsInFold and (tmpnode.StartLine + tmpnode.MergedLineCount - 1 = ToPos(TmpTxtIdx))
then TmpTxtIdx := TmpTxtIdx - node.MergedLineCount // Line before is in fold
else tmpnode.Init(nil, 0, 0);
NewCapability := FFoldProvider.LineCapabilities[TmpTxtIdx];
NewClassifications := FFoldProvider.LineClassification[TmpTxtIdx];
if (tmpnode.IsInFold) then begin
if tmpnode.IsHide then include(NewCapability, cfCollapsedHide)
else include(NewCapability, cfCollapsedFold);
include(NewClassifications, tmpnode.Page._Classification);
end;
TmpRange := NextLines.DisplayView.TextToViewIndex(TmpTxtIdx);
TmpViewIdx := TmpRange.Bottom;
end;
if TmpViewIdx <> TmpRange.Bottom then
exclude(NewCapability, cfFoldEnd);
if TmpViewIdx <> TmpRange.Top then begin
if NewCapability * [cfFoldStart, cfHideStart] <> [] then
NewCapability := NewCapability + [cfFoldBody];
NewCapability := NewCapability - [cfFoldStart, cfHideStart];
end; end;
TmpRange := NextLines.DisplayView.TextToViewIndex(TmpTxtIdx);
TmpViewIdx := TmpRange.Bottom;
end;
if TmpViewIdx <> TmpRange.Bottom then
exclude(NewCapability, cfFoldEnd);
if TmpViewIdx <> TmpRange.Top then begin
if NewCapability * [cfFoldStart, cfHideStart] <> [] then
NewCapability := NewCapability + [cfFoldBody];
NewCapability := NewCapability - [cfFoldStart, cfHideStart];
end; end;
// Add entry for line one above virtual topViewPos // Add entry for line one above virtual topViewPos
@ -3478,7 +3486,6 @@ begin
{$IFDEF SynFoldDebug}debugln(['FOLD-- CalculateMaps fTopViewPos:=', fTopViewPos, ' TxtIdx=',TxtIdx]);{$ENDIF} {$IFDEF SynFoldDebug}debugln(['FOLD-- CalculateMaps fTopViewPos:=', fTopViewPos, ' TxtIdx=',TxtIdx]);{$ENDIF}
cnt := NextLines.Count;
for i := 1 to fLinesInWindow + 2 do begin for i := 1 to fLinesInWindow + 2 do begin
if (TxtIdx >= cnt) or (TxtIdx < -1) then begin if (TxtIdx >= cnt) or (TxtIdx < -1) then begin
// Past end of Text // Past end of Text