mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-09-14 10:59:14 +02:00
synedit: moved fold code to TSynEditStringList, fixed folding after enter, bug #7773
git-svn-id: trunk@15990 -
This commit is contained in:
parent
3ca7d74abe
commit
5ebb7d717d
@ -661,6 +661,9 @@ type
|
|||||||
procedure ListDeleted(Index: integer);
|
procedure ListDeleted(Index: integer);
|
||||||
procedure ListInserted(Index: integer);
|
procedure ListInserted(Index: integer);
|
||||||
procedure ListPutted(Index: integer);
|
procedure ListPutted(Index: integer);
|
||||||
|
{$IFDEF SYN_LAZARUS}
|
||||||
|
procedure FoldChanged(Index: integer);
|
||||||
|
{$ENDIF}
|
||||||
procedure ListScanRanges(Sender: TObject);
|
procedure ListScanRanges(Sender: TObject);
|
||||||
procedure Loaded; override;
|
procedure Loaded; override;
|
||||||
procedure MarkListChange(Sender: TObject);
|
procedure MarkListChange(Sender: TObject);
|
||||||
@ -1445,6 +1448,9 @@ begin
|
|||||||
OnCleared := {$IFDEF FPC}@{$ENDIF}ListCleared;
|
OnCleared := {$IFDEF FPC}@{$ENDIF}ListCleared;
|
||||||
OnDeleted := {$IFDEF FPC}@{$ENDIF}ListDeleted;
|
OnDeleted := {$IFDEF FPC}@{$ENDIF}ListDeleted;
|
||||||
OnInserted := {$IFDEF FPC}@{$ENDIF}ListInserted;
|
OnInserted := {$IFDEF FPC}@{$ENDIF}ListInserted;
|
||||||
|
{$IFDEF SYN_LAZARUS}
|
||||||
|
OnFoldChanged := {$IFDEF FPC}@{$ENDIF}FoldChanged;
|
||||||
|
{$ENDIF}
|
||||||
OnPutted := {$IFDEF FPC}@{$ENDIF}ListPutted;
|
OnPutted := {$IFDEF FPC}@{$ENDIF}ListPutted;
|
||||||
// OnScanRanges := {$IFDEF FPC}@{$ENDIF}ListScanRanges;
|
// OnScanRanges := {$IFDEF FPC}@{$ENDIF}ListScanRanges;
|
||||||
end;
|
end;
|
||||||
@ -2879,80 +2885,13 @@ end;
|
|||||||
{$IFDEF SYN_LAZARUS}
|
{$IFDEF SYN_LAZARUS}
|
||||||
procedure TCustomSynEdit.CodeFoldAction(iLine: integer);
|
procedure TCustomSynEdit.CodeFoldAction(iLine: integer);
|
||||||
// iLine is 1 based as parameter
|
// iLine is 1 based as parameter
|
||||||
// and 0 based in the procedure below
|
// and 0 based in TSynEsitStringList
|
||||||
|
|
||||||
procedure UpdateFolded(var iLine: integer);
|
|
||||||
var
|
|
||||||
FoldType: TSynEditCodeFoldType;
|
|
||||||
Level: LongInt;
|
|
||||||
CurFoldType: TSynEditCodeFoldType;
|
|
||||||
SLines: TSynEditStringList;
|
|
||||||
begin
|
|
||||||
SLines:=TSynEditStringList(fLines);
|
|
||||||
FoldType:=SLines.FoldType[iLine];
|
|
||||||
Level:=SLines.FoldEndLevel[iLine];
|
|
||||||
if FoldType=cfCollapsed then begin
|
|
||||||
// fold all lines including sub blocks
|
|
||||||
inc(iLine);
|
|
||||||
while (iLine<Lines.Count)
|
|
||||||
and (SLines.FoldMinLevel[iLine]>=Level) do begin
|
|
||||||
//debugln('UpdateFolded Fold ',dbgs(iLine),' ',Lines[iLine]);
|
|
||||||
SLines.Folded[iLine]:=true;
|
|
||||||
inc(iLine);
|
|
||||||
end;
|
|
||||||
// fold last line of block
|
|
||||||
if (iLine<Lines.Count)
|
|
||||||
and (SLines.FoldType[iLine]=cfEnd) then begin
|
|
||||||
//debugln('UpdateFolded Fold END ',dbgs(iLine),' ',Lines[iLine]);
|
|
||||||
SLines.Folded[iLine]:=true;
|
|
||||||
inc(iLine);
|
|
||||||
end;
|
|
||||||
end else if FoldType=cfExpanded then begin
|
|
||||||
// expand all lines of this block and all sub expanded blocks
|
|
||||||
// sub blocks, that are collapsed, remain collapsed
|
|
||||||
inc(iLine);
|
|
||||||
while (iLine<Lines.Count)
|
|
||||||
and (SLines.FoldMinLevel[iLine]>=Level) do begin
|
|
||||||
//debugln('UpdateFolded Expand ',dbgs(iLine),' ',Lines[iLine]);
|
|
||||||
SLines.Folded[iLine]:=false;
|
|
||||||
CurFoldType:=SLines.FoldType[iLine];
|
|
||||||
if CurFoldType in [cfExpanded,cfCollapsed] then
|
|
||||||
UpdateFolded(iLine)
|
|
||||||
else
|
|
||||||
inc(iLine);
|
|
||||||
end;
|
|
||||||
// expand last line of block
|
|
||||||
if (iLine<Lines.Count)
|
|
||||||
and (SLines.FoldType[iLine]=cfEnd) then begin
|
|
||||||
//debugln('UpdateFolded Expand END ',dbgs(iLine),' ',Lines[iLine]);
|
|
||||||
SLines.Folded[iLine]:=false;
|
|
||||||
inc(iLine);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
var
|
|
||||||
FoldType: TSynEditCodeFoldType;
|
|
||||||
begin
|
begin
|
||||||
if (iLine<=0) or (iLine>Lines.Count) then exit;
|
if (iLine<=0) or (iLine>Lines.Count) then exit;
|
||||||
dec(iLine);
|
dec(iLine);
|
||||||
FoldType:=TSynEditStringList(fLines).FoldType[iLine];
|
case TSynEditStringList(fLines).FoldType[iLine] of
|
||||||
//debugln('TCustomSynEdit.CodeFoldAction A ',dbgs(iLine),' ',dbgs(ord(FoldType)));
|
cfExpanded : TSynEditStringList(fLines).FoldLines(iLine);
|
||||||
if FoldType in [cfExpanded,cfCollapsed] then begin
|
cfCollapsed : TSynEditStringList(fLines).UnFoldLines(iLine);
|
||||||
if FoldType=cfExpanded then begin
|
|
||||||
// collapse the branch
|
|
||||||
FoldType:=cfCollapsed;
|
|
||||||
//debugln('collapsing node: ',dbgs(iLine));
|
|
||||||
end else begin
|
|
||||||
// expand the branch
|
|
||||||
//debugln('expanding node: ',dbgs(iLine));
|
|
||||||
FoldType:=cfExpanded;
|
|
||||||
end;
|
|
||||||
//DebugLn(['TCustomSynEdit.CodeFoldAction iLine=',iLine]);
|
|
||||||
TSynEditStringList(fLines).FoldType[iLine] := FoldType;
|
|
||||||
UpdateFolded(iLine);
|
|
||||||
|
|
||||||
Invalidate;
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -2967,13 +2906,8 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TCustomSynEdit.UnfoldAll;
|
procedure TCustomSynEdit.UnfoldAll;
|
||||||
var
|
|
||||||
SLines: TSynEditStringList;
|
|
||||||
i: Integer;
|
|
||||||
begin
|
begin
|
||||||
SLines:=TSynEditStringList(Lines);
|
TSynEditStringList(Lines).UnfoldAll;
|
||||||
for i:=0 to SLines.Count-1 do
|
|
||||||
SLines.Folded[i]:=false;
|
|
||||||
Invalidate;
|
Invalidate;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -4881,6 +4815,8 @@ begin
|
|||||||
EnsureCursorPosVisible;
|
EnsureCursorPosVisible;
|
||||||
Include(fStateFlags, sfCaretChanged);
|
Include(fStateFlags, sfCaretChanged);
|
||||||
{$IFDEF SYN_LAZARUS}
|
{$IFDEF SYN_LAZARUS}
|
||||||
|
if TSynEditStringList(fLines).Folded[fCaretY - 1] then
|
||||||
|
TSynEditStringList(fLines).UnFoldLines(fCaretY - 1);
|
||||||
{$ELSE}
|
{$ELSE}
|
||||||
Include(fStateFlags, sfScrollbarChanged);
|
Include(fStateFlags, sfScrollbarChanged);
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
@ -5899,6 +5835,8 @@ function TCustomSynEdit.ScanFrom(Index: integer
|
|||||||
{$IFDEF SYN_LAZARUS}; AtLeastTilIndex: integer{$ENDIF}): integer;
|
{$IFDEF SYN_LAZARUS}; AtLeastTilIndex: integer{$ENDIF}): integer;
|
||||||
{$IFDEF SYN_LAZARUS}
|
{$IFDEF SYN_LAZARUS}
|
||||||
// Index and AtLeastTilIndex are 0 based
|
// Index and AtLeastTilIndex are 0 based
|
||||||
|
var
|
||||||
|
FixFStart: Integer;
|
||||||
|
|
||||||
procedure SetCodeFoldAttributes;
|
procedure SetCodeFoldAttributes;
|
||||||
var
|
var
|
||||||
@ -5906,13 +5844,17 @@ function TCustomSynEdit.ScanFrom(Index: integer
|
|||||||
CodeFoldEndLevel: LongInt;
|
CodeFoldEndLevel: LongInt;
|
||||||
CodeFoldType: TSynEditCodeFoldType;
|
CodeFoldType: TSynEditCodeFoldType;
|
||||||
LastCodeFoldEndLevel: LongInt;
|
LastCodeFoldEndLevel: LongInt;
|
||||||
|
i : integer;
|
||||||
|
UnFoldLevel: LongInt;
|
||||||
begin
|
begin
|
||||||
CodeFoldMinLevel:=fHighlighter.MinimumCodeFoldBlockLevel;
|
CodeFoldMinLevel:=fHighlighter.MinimumCodeFoldBlockLevel;
|
||||||
CodeFoldEndLevel:=fHighlighter.CurrentCodeFoldBlockLevel;
|
CodeFoldEndLevel:=fHighlighter.CurrentCodeFoldBlockLevel;
|
||||||
CodeFoldType:=cfNone;
|
CodeFoldType:=cfNone;
|
||||||
if CodeFoldEndLevel>CodeFoldMinLevel then begin
|
if CodeFoldEndLevel > CodeFoldMinLevel then begin
|
||||||
// block started (and not closed in the same line)
|
// block started (and not closed in the same line)
|
||||||
CodeFoldType:=cfExpanded;
|
if TSynEditStringList(Lines).FoldType[Result-1] = cfCollapsed
|
||||||
|
then CodeFoldType := cfCollapsed
|
||||||
|
else CodeFoldType := cfExpanded;
|
||||||
//debugln(['TCustomSynEdit.ScanFrom Block started Y=',Result,' MinLevel=',CodeFoldMinLevel,' EndLevel=',CodeFoldEndLevel,' CodeFoldType=',ord(CodeFoldType),' Line="',Lines[Result-1],'"']);
|
//debugln(['TCustomSynEdit.ScanFrom Block started Y=',Result,' MinLevel=',CodeFoldMinLevel,' EndLevel=',CodeFoldEndLevel,' CodeFoldType=',ord(CodeFoldType),' Line="',Lines[Result-1],'"']);
|
||||||
end else if (Result>1) then begin
|
end else if (Result>1) then begin
|
||||||
LastCodeFoldEndLevel:=TSynEditStringList(Lines).FoldEndLevel[Result-2];
|
LastCodeFoldEndLevel:=TSynEditStringList(Lines).FoldEndLevel[Result-2];
|
||||||
@ -5924,84 +5866,35 @@ function TCustomSynEdit.ScanFrom(Index: integer
|
|||||||
CodeFoldType:=cfContinue;
|
CodeFoldType:=cfContinue;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
// check if an cfEnd got removed
|
||||||
|
if (TSynEditStringList(Lines).FoldType[Result-1] = cfEnd)
|
||||||
|
and not(CodeFoldType = cfEnd) and (Result >= 2) then begin
|
||||||
|
// unfolde it; do not trust Folded[], as Fixfolded has not yet run
|
||||||
|
i := Result - 2;
|
||||||
|
UnFoldLevel := TSynEditStringList(Lines).FoldEndLevel[i];
|
||||||
|
while (i >= 0)
|
||||||
|
and (TSynEditStringList(Lines).FoldMinLevel[i] >= UnFoldLevel) do
|
||||||
|
dec(i);
|
||||||
|
if TSynEditStringList(Lines).FoldType[i] = cfCollapsed then begin
|
||||||
|
TSynEditStringList(Lines).FoldType[i] := cfExpanded;
|
||||||
|
if i < FixFStart then FixFStart := i;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
//DebugLn(['TCustomSynEdit.ScanFrom CodeFoldType=',SynEditCodeFoldTypeNames[CodeFoldType],' FoldMinLevel=',CodeFoldMinLevel,' FoldEndLevel=',CodeFoldEndLevel,' Folded=',false]);
|
//DebugLn(['TCustomSynEdit.ScanFrom CodeFoldType=',SynEditCodeFoldTypeNames[CodeFoldType],' FoldMinLevel=',CodeFoldMinLevel,' FoldEndLevel=',CodeFoldEndLevel,' Folded=',false]);
|
||||||
TSynEditStringList(Lines).FoldMinLevel[Result-1] := CodeFoldMinLevel;
|
TSynEditStringList(Lines).FoldMinLevel[Result-1] := CodeFoldMinLevel;
|
||||||
TSynEditStringList(Lines).FoldEndLevel[Result-1] := CodeFoldEndLevel;
|
TSynEditStringList(Lines).FoldEndLevel[Result-1] := CodeFoldEndLevel;
|
||||||
TSynEditStringList(Lines).FoldType[Result-1] := CodeFoldType;
|
TSynEditStringList(Lines).FoldType[Result-1] := CodeFoldType;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure CheckFolded(FromIndex, ToIndex: integer);
|
|
||||||
{ Checks/Updates the Folded attributes of every scanned line
|
|
||||||
|
|
||||||
}
|
|
||||||
var
|
|
||||||
i: LongInt;
|
|
||||||
FoldStart: LongInt;
|
|
||||||
FoldLevel: LongInt;
|
|
||||||
SLines: TSynEditStringList;
|
|
||||||
begin
|
|
||||||
i:=FromIndex;
|
|
||||||
if i<0 then i:=0;
|
|
||||||
if i>ToIndex then exit;
|
|
||||||
SLines:=TSynEditStringList(Lines);
|
|
||||||
// find start and level of folded block at start of scan range
|
|
||||||
if SLines.Folded[i] then begin
|
|
||||||
FoldStart:=i;
|
|
||||||
while (FoldStart>0) and SLines.Folded[FoldStart] do
|
|
||||||
dec(FoldStart);
|
|
||||||
FoldLevel:=SLines.FoldEndLevel[FoldStart];
|
|
||||||
//DebugLn(['CheckFolded First FoldStart=',FoldStart,' FoldLevel=',FoldLevel,' Line="',Lines[FoldStart],'"']);
|
|
||||||
end else begin
|
|
||||||
FoldStart:=-1;
|
|
||||||
FoldLevel:=0;
|
|
||||||
end;
|
|
||||||
// check and fix 'folded' attributes of scanned range
|
|
||||||
while i<=ToIndex do begin
|
|
||||||
if FoldLevel<=0 then begin
|
|
||||||
// last line is not folded
|
|
||||||
if not SLines.Folded[i] then begin
|
|
||||||
// this line was not folded
|
|
||||||
// no change needed
|
|
||||||
end else begin
|
|
||||||
// this line was folded
|
|
||||||
if (i>0) and (SLines.FoldMinLevel[i-1]>=SLines.FoldEndLevel[i-1]) then
|
|
||||||
begin
|
|
||||||
// last line did not contain a block start
|
|
||||||
// => unfolded block must continue
|
|
||||||
SLines.Folded[i]:=false;
|
|
||||||
FoldLevel:=0;
|
|
||||||
//DebugLn(['CheckFolded Change A Folded of line ',i,' to FoldStart=',FoldStart,' FoldLevel=',FoldLevel,' Line="',Lines[i],'" SLines.Folded[i]=',SLines.Folded[i]]);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end else begin
|
|
||||||
// last line is folded
|
|
||||||
if SLines.Folded[i] then begin
|
|
||||||
// this line was folded
|
|
||||||
if (i>0) and (SLines.FoldEndLevel[i-1]<FoldLevel) then begin
|
|
||||||
// last fold block ended with last line
|
|
||||||
FoldStart:=i;
|
|
||||||
FoldLevel:=SLines.FoldMinLevel[FoldStart];
|
|
||||||
SLines.Folded[i]:=false;
|
|
||||||
//DebugLn(['CheckFolded Change B Folded of line ',i,' to FoldStart=',FoldStart,' FoldLevel=',FoldLevel,' Line="',Lines[i],'" SLines.Folded[i]=',SLines.Folded[i]]);
|
|
||||||
end;
|
|
||||||
end else begin
|
|
||||||
// this line was not folded
|
|
||||||
if (i>0) and (SLines.FoldEndLevel[i-1]>=FoldLevel) then begin
|
|
||||||
// current folded block must be continued
|
|
||||||
SLines.Folded[i]:=true;
|
|
||||||
//DebugLn(['CheckFolded Change C Folded of line ',i,' to FoldStart=',FoldStart,' FoldLevel=',FoldLevel,' Line="',Lines[i],'" SLines.Folded[i]=',SLines.Folded[i]]);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
inc(i);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
|
||||||
begin
|
begin
|
||||||
Result := Index;
|
Result := Index;
|
||||||
if Index >= Lines.Count - 1 then Exit;
|
if Index >= Lines.Count - 1 then Exit;
|
||||||
//debugln('TCustomSynEdit.ScanFrom A Index=',dbgs(Index),' Line="',Lines[Index],'"');
|
//debugln('TCustomSynEdit.ScanFrom A Index=',dbgs(Index),' Line="',Lines[Index],'"');
|
||||||
|
{$IFDEF SYN_LAZARUS}
|
||||||
|
FixFStart := Index;
|
||||||
|
{$ENDIF}
|
||||||
fHighlighter.SetLine(Lines[Result], Result);
|
fHighlighter.SetLine(Lines[Result], Result);
|
||||||
inc(Result);
|
inc(Result);
|
||||||
fHighlighter.NextToEol;
|
fHighlighter.NextToEol;
|
||||||
@ -6027,12 +5920,16 @@ begin
|
|||||||
break;
|
break;
|
||||||
end;
|
end;
|
||||||
{$IFDEF SYN_LAZARUS}
|
{$IFDEF SYN_LAZARUS}
|
||||||
if (Result>Index+1) and (Result<=Lines.Count) then begin
|
// at least one line changed
|
||||||
// at least one line changed
|
// => update code fold attributes of last scanned line
|
||||||
// => update code fold attributes of last scanned line
|
if (Result>Index+1) and (Result<=Lines.Count) then
|
||||||
SetCodeFoldAttributes;
|
SetCodeFoldAttributes;
|
||||||
end;
|
TSynEditStringList(Lines).FixFolding(FixFStart, Result);
|
||||||
CheckFolded(Index,Result);
|
if TSynEditStringList(fLines).Folded[fCaretY - 1] then
|
||||||
|
TSynEditStringList(fLines).UnFoldLines(fCaretY - 1);
|
||||||
|
if TSynEditStringList(Lines).Folded[TopLine] then
|
||||||
|
TopLine := FindNextUnfoldedLine(TopLine, False);
|
||||||
|
if FixFStart < index then Invalidate;
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
Dec(Result);
|
Dec(Result);
|
||||||
end;
|
end;
|
||||||
@ -6178,6 +6075,18 @@ begin
|
|||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{$IFDEF SYN_LAZARUS}
|
||||||
|
procedure TCustomSynEdit.FoldChanged(Index : integer);
|
||||||
|
begin
|
||||||
|
if Index + 1 > ScreenRowToRow(LinesInWindow + 1) then exit;
|
||||||
|
if Index + 1 < TopLine then Index := TopLine;
|
||||||
|
if TSynEditStringList(Lines).Folded[TopLine] then
|
||||||
|
TopLine := FindNextUnfoldedLine(TopLine, False);
|
||||||
|
InvalidateLines(Index + 1, ScreenRowToRow(LinesInWindow + 1));
|
||||||
|
InvalidateGutterLines(Index + 1, ScreenRowToRow(LinesInWindow + 1));
|
||||||
|
end;
|
||||||
|
{$ENDIF}
|
||||||
|
|
||||||
procedure TCustomSynEdit.ListScanRanges(Sender: TObject);
|
procedure TCustomSynEdit.ListScanRanges(Sender: TObject);
|
||||||
{$IFNDEF SYN_LAZARUS}
|
{$IFNDEF SYN_LAZARUS}
|
||||||
var
|
var
|
||||||
@ -7635,6 +7544,7 @@ var
|
|||||||
LogCaret: TPoint;
|
LogCaret: TPoint;
|
||||||
LogSpacePos: integer;
|
LogSpacePos: integer;
|
||||||
LastUndoItem:TSynEditUndoItem;
|
LastUndoItem:TSynEditUndoItem;
|
||||||
|
CY: Integer;
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
|
||||||
{begin} //mh 2000-10-30
|
{begin} //mh 2000-10-30
|
||||||
@ -7800,6 +7710,10 @@ begin
|
|||||||
Caret := CaretXY;
|
Caret := CaretXY;
|
||||||
CaretNew := PrevWordPos;
|
CaretNew := PrevWordPos;
|
||||||
{$IFDEF SYN_LAZARUS}
|
{$IFDEF SYN_LAZARUS}
|
||||||
|
if TSynEditStringList(fLines).Folded[CaretNew.Y - 1] then begin
|
||||||
|
CY := FindNextUnfoldedLine(CaretNew.Y, False);
|
||||||
|
CaretNew := LogicalToPhysicalPos(Point(1 + Length(fLines[CY-1]), CY));
|
||||||
|
end;
|
||||||
MoveCaretAndSelectionPhysical
|
MoveCaretAndSelectionPhysical
|
||||||
{$ELSE}
|
{$ELSE}
|
||||||
MoveCaretAndSelection
|
MoveCaretAndSelection
|
||||||
@ -7815,6 +7729,8 @@ begin
|
|||||||
Caret := CaretXY;
|
Caret := CaretXY;
|
||||||
CaretNew := NextWordPos;
|
CaretNew := NextWordPos;
|
||||||
{$IFDEF SYN_LAZARUS}
|
{$IFDEF SYN_LAZARUS}
|
||||||
|
if TSynEditStringList(fLines).Folded[CaretNew.Y - 1] then
|
||||||
|
CaretNew := Point(1, FindNextUnfoldedLine(CaretNew.Y, True));
|
||||||
MoveCaretAndSelectionPhysical
|
MoveCaretAndSelectionPhysical
|
||||||
{$ELSE}
|
{$ELSE}
|
||||||
MoveCaretAndSelection
|
MoveCaretAndSelection
|
||||||
|
@ -150,6 +150,9 @@ type
|
|||||||
fOnDeleted: TStringListIndexEvent;
|
fOnDeleted: TStringListIndexEvent;
|
||||||
fOnInserted: TStringListIndexEvent;
|
fOnInserted: TStringListIndexEvent;
|
||||||
fOnPutted: TStringListIndexEvent;
|
fOnPutted: TStringListIndexEvent;
|
||||||
|
{$IFDEF SYN_LAZARUS}
|
||||||
|
fOnFoldChanged: TStringListIndexEvent;
|
||||||
|
{$ENDIF}
|
||||||
function Get(Index: integer): string; override;
|
function Get(Index: integer): string; override;
|
||||||
function GetCapacity: integer;
|
function GetCapacity: integer;
|
||||||
{$IFDEF SYN_COMPILER_3_UP} override; {$ENDIF} //mh 2000-10-18
|
{$IFDEF SYN_COMPILER_3_UP} override; {$ENDIF} //mh 2000-10-18
|
||||||
@ -163,6 +166,7 @@ type
|
|||||||
procedure SetUpdateState(Updating: Boolean); override;
|
procedure SetUpdateState(Updating: Boolean); override;
|
||||||
{$IFDEF SYN_LAZARUS}
|
{$IFDEF SYN_LAZARUS}
|
||||||
procedure SetTextStr(const Value: string); override;
|
procedure SetTextStr(const Value: string); override;
|
||||||
|
procedure MaybeUnfoldAboveNewLine(ANewLineIndex: Integer);
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
public
|
public
|
||||||
constructor Create;
|
constructor Create;
|
||||||
@ -180,6 +184,10 @@ type
|
|||||||
procedure SaveToFile(const FileName: string); override;
|
procedure SaveToFile(const FileName: string); override;
|
||||||
{$IFDEF SYN_LAZARUS}
|
{$IFDEF SYN_LAZARUS}
|
||||||
procedure ClearRanges(ARange: TSynEditRange);
|
procedure ClearRanges(ARange: TSynEditRange);
|
||||||
|
procedure FoldLines(AStartIndex: Integer);
|
||||||
|
procedure UnFoldLines(AStartIndex: Integer);
|
||||||
|
procedure UnfoldAll;
|
||||||
|
procedure FixFolding(AStartIndex: Integer; AMinEndIndex: Integer = 0);
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
public
|
public
|
||||||
property DosFileFormat: boolean read fDosFileFormat write fDosFileFormat;
|
property DosFileFormat: boolean read fDosFileFormat write fDosFileFormat;
|
||||||
@ -198,6 +206,8 @@ type
|
|||||||
write fOnInserted;
|
write fOnInserted;
|
||||||
property OnPutted: TStringListIndexEvent read fOnPutted write fOnPutted;
|
property OnPutted: TStringListIndexEvent read fOnPutted write fOnPutted;
|
||||||
{$IFDEF SYN_LAZARUS}
|
{$IFDEF SYN_LAZARUS}
|
||||||
|
property OnFoldChanged: TStringListIndexEvent read fOnFoldChanged
|
||||||
|
write fOnFoldChanged;
|
||||||
property Folded[Index: integer]: boolean read GetFolded write SetFolded;
|
property Folded[Index: integer]: boolean read GetFolded write SetFolded;
|
||||||
property FoldMinLevel[Index: integer]: integer read GetFoldMinLevel
|
property FoldMinLevel[Index: integer]: integer read GetFoldMinLevel
|
||||||
write SetFoldMinLevel;
|
write SetFoldMinLevel;
|
||||||
@ -527,6 +537,9 @@ begin
|
|||||||
BeginUpdate;
|
BeginUpdate;
|
||||||
Result := fCount;
|
Result := fCount;
|
||||||
InsertItem(Result, S);
|
InsertItem(Result, S);
|
||||||
|
{$IFDEF SYN_LAZARUS}
|
||||||
|
MaybeUnfoldAboveNewLine(Result);
|
||||||
|
{$ENDIF}
|
||||||
if Assigned(fOnAdded) then
|
if Assigned(fOnAdded) then
|
||||||
fOnAdded(Result);
|
fOnAdded(Result);
|
||||||
EndUpdate;
|
EndUpdate;
|
||||||
@ -562,6 +575,9 @@ begin
|
|||||||
end;
|
end;
|
||||||
Inc(fCount);
|
Inc(fCount);
|
||||||
end;
|
end;
|
||||||
|
{$IFDEF SYN_LAZARUS}
|
||||||
|
MaybeUnfoldAboveNewLine(FirstAdded);
|
||||||
|
{$ENDIF}
|
||||||
if Assigned(fOnAdded) then
|
if Assigned(fOnAdded) then
|
||||||
fOnAdded(FirstAdded);
|
fOnAdded(FirstAdded);
|
||||||
finally
|
finally
|
||||||
@ -877,6 +893,9 @@ begin
|
|||||||
ListIndexOutOfBounds(Index);
|
ListIndexOutOfBounds(Index);
|
||||||
BeginUpdate;
|
BeginUpdate;
|
||||||
InsertItem(Index, S);
|
InsertItem(Index, S);
|
||||||
|
{$IFDEF SYN_LAZARUS}
|
||||||
|
MaybeUnfoldAboveNewLine(Index);
|
||||||
|
{$ENDIF}
|
||||||
if Assigned(fOnInserted) then
|
if Assigned(fOnInserted) then
|
||||||
fOnInserted(Index);
|
fOnInserted(Index);
|
||||||
EndUpdate;
|
EndUpdate;
|
||||||
@ -928,6 +947,9 @@ begin
|
|||||||
end;
|
end;
|
||||||
FillChar(fList^[Index], NumLines * SynEditStringRecSize, 0);
|
FillChar(fList^[Index], NumLines * SynEditStringRecSize, 0);
|
||||||
Inc(fCount, NumLines);
|
Inc(fCount, NumLines);
|
||||||
|
{$IFDEF SYN_LAZARUS}
|
||||||
|
MaybeUnfoldAboveNewLine(Index);
|
||||||
|
{$ENDIF}
|
||||||
if Assigned(fOnAdded) then
|
if Assigned(fOnAdded) then
|
||||||
fOnAdded(Index);
|
fOnAdded(Index);
|
||||||
finally
|
finally
|
||||||
@ -1048,6 +1070,124 @@ begin
|
|||||||
for Index:=0 to fCount-1 do
|
for Index:=0 to fCount-1 do
|
||||||
fList^[Index].fRange := ARange;
|
fList^[Index].fRange := ARange;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TSynEditStringList.FoldLines(AStartIndex : Integer);
|
||||||
|
begin
|
||||||
|
//debugln(['TSynEditStringList.FoldLines AstartIndex=', AStartIndex, ' FoldType=', ord(FoldType[AStartIndex]), ' Folded=',dbgs(Folded[AStartIndex]) ]);
|
||||||
|
if (AStartIndex < 0) or (AStartIndex >= Count)
|
||||||
|
or not (FoldType[AStartIndex] = cfExpanded) then exit;
|
||||||
|
|
||||||
|
FoldType[AStartIndex] := cfCollapsed;
|
||||||
|
FixFolding(AStartIndex);
|
||||||
|
|
||||||
|
if Assigned(fOnFoldChanged) then
|
||||||
|
fOnFoldChanged(AStartIndex);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TSynEditStringList.UnFoldLines(AStartIndex : Integer);
|
||||||
|
var
|
||||||
|
i1, i2: LongInt;
|
||||||
|
begin
|
||||||
|
//debugln(['TSynEditStringList.UnFoldLines AstartIndex=', AStartIndex, ' FoldType(0=nil;1=col;2=exp)=', ord(FoldType[AStartIndex]), ' Folded=',dbgs(Folded[AStartIndex]) ]);
|
||||||
|
if (AStartIndex < 0) or (AStartIndex >= Count)
|
||||||
|
and ((FoldType[AStartIndex] = cfCollapsed) or Folded[AStartIndex])
|
||||||
|
then exit;
|
||||||
|
|
||||||
|
if Folded[AStartIndex] then begin
|
||||||
|
i2 := AStartIndex;
|
||||||
|
while Folded[AStartIndex] do begin
|
||||||
|
i1 := AStartIndex-1;
|
||||||
|
while (i1 >= 0) and Folded[i1] do dec(i1);
|
||||||
|
FoldType[i1] := cfExpanded;
|
||||||
|
FixFolding(i1);
|
||||||
|
if i1 < i2 then i2 := i1;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if Assigned(fOnFoldChanged) then
|
||||||
|
fOnFoldChanged(i2);
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
|
||||||
|
FoldType[AStartIndex] := cfExpanded;
|
||||||
|
FixFolding(AStartIndex);
|
||||||
|
if Assigned(fOnFoldChanged) then
|
||||||
|
fOnFoldChanged(AStartIndex);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TSynEditStringList.UnfoldAll;
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
|
begin
|
||||||
|
for i:=0 to Count-1 do begin
|
||||||
|
Folded[i]:=false;
|
||||||
|
if FoldType[i] = cfCollapsed then FoldType[i] := cfExpanded;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TSynEditStringList.FixFolding(AStartIndex: integer; AMinEndIndex : Integer = 0);
|
||||||
|
var
|
||||||
|
Level, CoLevel: LongInt;
|
||||||
|
cnt, i: Integer;
|
||||||
|
begin
|
||||||
|
cnt := Count;
|
||||||
|
if (AStartIndex < 0) or (AStartIndex >= cnt) then exit;
|
||||||
|
//debugln(['TSynEditStringList.FixFolding AStartIndex=', AStartIndex, ' AMinEndindex=', AMinEndIndex, ' FoldType(0=nil;1=col;2=exp)=', ord(FoldType[AStartIndex]), ' Folded=',dbgs(Folded[AStartIndex]) ]);
|
||||||
|
|
||||||
|
// Always do the current line
|
||||||
|
if AMinEndIndex < AStartIndex then AMinEndIndex := AStartIndex;
|
||||||
|
// Always start from unfolded line
|
||||||
|
while (AStartIndex > 0) and Folded[AStartIndex] do
|
||||||
|
dec(AStartIndex);
|
||||||
|
// Remember current Level, fix must run at least to the end of current level
|
||||||
|
Level := FoldEndLevel[AStartIndex];
|
||||||
|
|
||||||
|
while (AStartIndex < cnt)
|
||||||
|
and ((FoldMinLevel[AStartIndex] >= Level) or (AStartIndex <= AMinEndIndex))
|
||||||
|
do begin
|
||||||
|
if (FoldType[AStartIndex] = cfCollapsed) then begin
|
||||||
|
// begin of a new fold; keep first line visible
|
||||||
|
Folded[AStartIndex] := False;
|
||||||
|
CoLevel := FoldEndLevel[AStartIndex];
|
||||||
|
inc(AStartIndex);
|
||||||
|
while (AStartIndex < cnt)
|
||||||
|
and (FoldMinLevel[AStartIndex] >= CoLevel) do begin
|
||||||
|
Folded[AStartIndex] := true;
|
||||||
|
inc(AStartIndex);
|
||||||
|
end;
|
||||||
|
// fold last line of block
|
||||||
|
if (AStartIndex < cnt)
|
||||||
|
and (FoldType[AStartIndex] = cfEnd) then begin
|
||||||
|
Folded[AStartIndex] := true;
|
||||||
|
inc(AStartIndex);
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
//unfolded
|
||||||
|
Folded[AStartIndex] := false;
|
||||||
|
inc(AStartIndex);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
// last line of block, if cfEnd (otherwise the next block begins here)
|
||||||
|
if (AStartIndex < cnt)
|
||||||
|
and (FoldType[AStartIndex] = cfEnd) then
|
||||||
|
Folded[AStartIndex] := false;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TSynEditStringList.MaybeUnfoldAboveNewLine(ANewLineIndex : Integer);
|
||||||
|
begin
|
||||||
|
exit;
|
||||||
|
if ANewLineIndex = 0 then exit;
|
||||||
|
if (FoldType[ANewLineIndex - 1] = cfCollapsed)
|
||||||
|
and not Folded[ANewLineIndex - 1] then begin
|
||||||
|
FoldType[ANewLineIndex - 1] := cfExpanded;
|
||||||
|
// ScanFrom will override this, unless we moved a "begin" from the previous line
|
||||||
|
FoldType[ANewLineIndex] := cfCollapsed;
|
||||||
|
if Assigned(fOnFoldChanged) then
|
||||||
|
fOnFoldChanged(ANewLineIndex - 1);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
{$ENDIF}
|
{$ENDIF}
|
||||||
|
|
||||||
procedure TSynEditStringList.SetCapacity(NewCapacity: integer);
|
procedure TSynEditStringList.SetCapacity(NewCapacity: integer);
|
||||||
|
Loading…
Reference in New Issue
Block a user