mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-28 22:20:25 +02:00
Added SynEdit.FoldAll (bug #12561, modified/ext patch from Brad Campbell)
Added Methods to find Collapsed/Expanded Line for block around cursor git-svn-id: trunk@17279 -
This commit is contained in:
parent
9a0a1e6215
commit
4c1df45cac
@ -754,6 +754,7 @@ type
|
||||
procedure CodeFoldAction(iLine: integer);
|
||||
function FindNextUnfoldedLine(iLine: integer; Down: boolean): Integer;
|
||||
procedure UnfoldAll;
|
||||
procedure FoldAll(StartLevel : Integer = 0; IgnoreNested : Boolean = False);
|
||||
{$ENDIF}
|
||||
|
||||
procedure AddKey(Command: TSynEditorCommand; Key1: word; SS1: TShiftState;
|
||||
@ -2929,6 +2930,11 @@ begin
|
||||
Invalidate;
|
||||
end;
|
||||
|
||||
procedure TCustomSynEdit.FoldAll(StartLevel : Integer = 0; IgnoreNested : Boolean = False);
|
||||
begin
|
||||
fTextView.FoldAll(StartLevel, IgnoreNested);
|
||||
Invalidate;
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
procedure TCustomSynEdit.PaintGutter(AClip: TRect; FirstLine, LastLine: integer);
|
||||
@ -6078,13 +6084,20 @@ end;
|
||||
|
||||
{$IFDEF SYN_LAZARUS}
|
||||
procedure TCustomSynEdit.FoldChanged(Index : integer);
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
TopLine := TopLine;
|
||||
i := fTextView.CollapsedLineForFoldAtLine(CaretY);
|
||||
if i > 0 then
|
||||
SetCaretXY(Point(1, i))
|
||||
else
|
||||
EnsureCursorPosVisible;
|
||||
UpdateScrollBars;
|
||||
if Index + 1 > ScreenRowToRow(LinesInWindow + 1) then exit;
|
||||
if Index + 1 < TopLine then Index := TopLine;
|
||||
TopLine := TopLine;
|
||||
InvalidateLines(Index + 1, ScreenRowToRow(LinesInWindow + 1));
|
||||
InvalidateGutterLines(Index + 1, ScreenRowToRow(LinesInWindow + 1));
|
||||
UpdateScrollBars;
|
||||
end;
|
||||
|
||||
procedure TCustomSynEdit.SetTopView(const AValue : Integer);
|
||||
|
@ -171,7 +171,6 @@ type
|
||||
fOnFoldChanged : TFoldChangedEvent;
|
||||
fCFDividerDrawLevel: Integer;
|
||||
|
||||
procedure debug;
|
||||
function GetCount : integer;
|
||||
function GetDrawDivider(Index : integer) : Boolean;
|
||||
function GetLines(index : Integer) : String;
|
||||
@ -203,6 +202,7 @@ type
|
||||
constructor Create(aTextBuffer : TSynEditStringList);
|
||||
destructor Destroy; override;
|
||||
|
||||
// Converting between Folded and Unfolded Lines/Indexes
|
||||
function TextIndexToViewPos(aTextIndex : Integer) : Integer; (* Convert TextIndex (0-based) to ViewPos (1-based) *)
|
||||
function TextIndexToScreenLine(aTextIndex : Integer) : Integer; (* Convert TextIndex (0-based) to Screen (0-based) *)
|
||||
function ViewPosToTextIndex(aViewPos : Integer) : Integer; (* Convert ViewPos (1-based) to TextIndex (0-based) *)
|
||||
@ -211,6 +211,7 @@ type
|
||||
function TextIndexAddLines(aTextIndex, LineOffset : Integer) : Integer; (* Add/Sub to/from TextIndex (0-based) skipping folded *)
|
||||
function TextPosAddLines(aTextpos, LineOffset : Integer) : Integer; (* Add/Sub to/from TextPos (1-based) skipping folded *)
|
||||
|
||||
// Attributes for Visible-Lines-On-screen
|
||||
property Lines[index : Integer] : String (* Lines on screen / 0 = TopLine *)
|
||||
read GetLines; default;
|
||||
property Ranges[Index: integer]: TSynEditRange
|
||||
@ -224,6 +225,7 @@ type
|
||||
property TextIndex[index : Integer] : Integer (* Position in SynTextBuffer / result is 0-based *)
|
||||
read GetTextIndex; // maybe writable
|
||||
|
||||
// Define Visible Area
|
||||
property TopLine : integer (* refers to visible (unfolded) lines / 1-based *)
|
||||
read fTopLine write SetTopLine;
|
||||
property TopTextIndex : integer (* refers to TextIndex (folded + unfolded lines) / 1-based *)
|
||||
@ -236,6 +238,8 @@ type
|
||||
property CFDividerDrawLevel: Integer read fCFDividerDrawLevel write fCFDividerDrawLevel;
|
||||
|
||||
public
|
||||
procedure debug;
|
||||
// Action Fold/Unfold
|
||||
procedure FoldAtLine(AStartLine: Integer); (* Folds at ScreenLine / 0-based *)
|
||||
procedure FoldAtViewPos(AStartPos: Integer); (* Folds at nth visible/unfolded Line / 1-based *)
|
||||
procedure FoldAtTextIndex(AStartIndex: Integer); (* Folds at nth TextIndex (all lines in buffer) / 1-based *)
|
||||
@ -244,11 +248,17 @@ type
|
||||
procedure UnFoldAtTextIndex(AStartIndex: Integer; IgnoreFirst : Boolean = False); (* UnFolds at nth TextIndex (all lines in buffer) / 1-based *)
|
||||
|
||||
procedure UnfoldAll;
|
||||
procedure FoldAll(StartLevel : Integer = 0; IgnoreNested : Boolean = False);
|
||||
procedure FixFoldingAtTextIndex(AStartIndex: Integer; AMinEndLine: Integer = 0); // Real/All lines
|
||||
|
||||
// Find the visible first line of the fold at ALine. Returns -1 if Aline is not folded
|
||||
function CollapsedLineForFoldAtLine(ALine : Integer) : Integer;
|
||||
function ExpandedLineForBlockAtLine(ALine : Integer) : Integer;
|
||||
|
||||
property FoldedAtTextIndex [index : integer] : Boolean read IsFolded;
|
||||
|
||||
property OnFoldChanged: TFoldChangedEvent (* reports 1-based line *) {TODO: synedit expects 0 based }
|
||||
read fOnFoldChanged write fOnFoldChanged;
|
||||
property FoldedAtTextIndex [index : integer] : Boolean read IsFolded;
|
||||
end;
|
||||
|
||||
|
||||
@ -902,11 +912,17 @@ begin
|
||||
|
||||
rFoldedBefore := rFoldedBefore + current.LeftCount;
|
||||
if ALine = rStartLine then begin
|
||||
if ACount < current.LineCount
|
||||
(* *** New Block will be nested in current *** *)
|
||||
then NestNewBlockIntoCurrent
|
||||
(* *** current will be nested in New Block *** *)
|
||||
else NestCurrentIntoNewBlock;
|
||||
if ACount < current.LineCount then
|
||||
(* *** New Block will be nested in current *** *)
|
||||
NestNewBlockIntoCurrent
|
||||
else
|
||||
if ACount > current.LineCount then
|
||||
(* *** current will be nested in New Block *** *)
|
||||
NestCurrentIntoNewBlock
|
||||
else begin
|
||||
debugln(['Droping Foldnode / Already exists. Startline=', rStartLine,' LineCount=',ACount]);
|
||||
ANode.Free;
|
||||
end;
|
||||
end
|
||||
else begin
|
||||
If ALine <= rStartLine + current.LineCount - 1
|
||||
@ -1598,6 +1614,31 @@ begin
|
||||
fOnFoldChanged(0);
|
||||
end;
|
||||
|
||||
procedure TSynEditFoldedView.FoldAll(StartLevel : Integer = 0; IgnoreNested : Boolean = False);
|
||||
var
|
||||
i, l, top: Integer;
|
||||
begin
|
||||
top := TopTextIndex;
|
||||
fFoldTree.Clear;
|
||||
i := 0;
|
||||
while i < fLines.Count do begin
|
||||
if (fLines.FoldEndLevel[i] > fLines.FoldMinLevel[i])
|
||||
and (fLines.FoldEndLevel[i] > StartLevel) then begin
|
||||
l := LengthForFoldAtTextIndex(i);
|
||||
// i is 0-based
|
||||
// FoldTree is 1-based AND first line remains visble
|
||||
fFoldTree.InsertNewFold(i+2, l);
|
||||
if IgnoreNested then
|
||||
i := i + l;
|
||||
end;
|
||||
inc(i);
|
||||
end;
|
||||
fTopLine := -1;
|
||||
TopTextIndex := top;
|
||||
if Assigned(fOnFoldChanged) then
|
||||
fOnFoldChanged(0);
|
||||
end;
|
||||
|
||||
function TSynEditFoldedView.FixFolding(AStart : Integer; AMinEnd : Integer; aFoldTree : TSynTextFoldAVLTree) : Boolean;
|
||||
var
|
||||
line, a : Integer;
|
||||
@ -1661,6 +1702,52 @@ begin
|
||||
FixFolding(AStartIndex + 1, AMinEndLine, fFoldTree);
|
||||
end;
|
||||
|
||||
function TSynEditFoldedView.ExpandedLineForBlockAtLine(ALine : Integer) : Integer;
|
||||
var
|
||||
i, l : Integer;
|
||||
node: TSynTextFoldAVLNode;
|
||||
begin
|
||||
Result := -1;
|
||||
i := ALine-1;
|
||||
|
||||
if (i>0) and (fLines.FoldMinLevel[i] < fLines.FoldEndLevel[i-1])then begin
|
||||
if fLines.FoldMinLevel[i] < fLines.FoldEndLevel[i] then begin
|
||||
// this is a combined "end begin" line
|
||||
node := fFoldTree.FindFoldForLine(ALine, true);
|
||||
if node.IsInFold and (node.StartLine = ALine +1) then
|
||||
dec(i);
|
||||
if i < 0 then exit;
|
||||
end else begin
|
||||
// this is a "end" line
|
||||
dec(i);
|
||||
end;
|
||||
l := fLines.FoldEndLevel[i];
|
||||
end else if fLines.FoldEndLevel[i] = 0 then
|
||||
exit
|
||||
else begin
|
||||
// check if current line is cfCollapsed
|
||||
node := fFoldTree.FindFoldForLine(ALine, true);
|
||||
if node.IsInFold and (node.StartLine = ALine +1) then
|
||||
dec(i);
|
||||
if i < 0 then exit;
|
||||
l := fLines.FoldEndLevel[i]
|
||||
end;
|
||||
|
||||
while (i > 0) and (fLines.FoldMinLevel[i] >= l) do
|
||||
dec(i);
|
||||
if (fLines.FoldEndLevel[i] > 0) then // TODO, check for collapsed at index = 0
|
||||
Result := i + 1;
|
||||
end;
|
||||
|
||||
function TSynEditFoldedView.CollapsedLineForFoldAtLine(ALine : Integer) : Integer;
|
||||
var
|
||||
node: TSynTextFoldAVLNode;
|
||||
begin
|
||||
Result := -1;
|
||||
node := fFoldTree.FindFoldForLine(ALine, false);
|
||||
if node.IsInFold then Result := node.StartLine-1;
|
||||
end;
|
||||
|
||||
procedure TSynEditFoldedView.debug;
|
||||
procedure debug2(ind, typ : String; ANode, AParent : TSynTextFoldAVLNodeData; offset : integer);
|
||||
begin
|
||||
|
Loading…
Reference in New Issue
Block a user