mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-11-23 20:00:03 +01:00
IDE: code explorer: follow cursor
git-svn-id: trunk@26492 -
This commit is contained in:
parent
1317f884b2
commit
7b45c23d5e
@ -222,7 +222,7 @@ type
|
|||||||
procedure UpdateMode;
|
procedure UpdateMode;
|
||||||
protected
|
protected
|
||||||
fLastCodeTool: TCodeTool;
|
fLastCodeTool: TCodeTool;
|
||||||
fCodeSortedForStartPos: TAvgLvlTree;// tree of TTreeNode sorted for TViewNodeData(Node.Data).StartPos
|
fCodeSortedForStartPos: TAvgLvlTree;// tree of TTreeNode sorted for TViewNodeData(Node.Data).StartPos, secondary EndPos
|
||||||
procedure ApplyCodeFilter;
|
procedure ApplyCodeFilter;
|
||||||
procedure ApplyDirectivesFilter;
|
procedure ApplyDirectivesFilter;
|
||||||
function CompareCodeNodes(Node1, Node2: TTreeNode): integer;
|
function CompareCodeNodes(Node1, Node2: TTreeNode): integer;
|
||||||
@ -285,7 +285,7 @@ implementation
|
|||||||
type
|
type
|
||||||
TViewNodeData = class
|
TViewNodeData = class
|
||||||
public
|
public
|
||||||
CTNode: TCodeTreeNode;
|
CTNode: TCodeTreeNode; // only valid during update, other times it is nil
|
||||||
Desc: TCodeTreeNodeDesc;
|
Desc: TCodeTreeNodeDesc;
|
||||||
SubDesc: TCodeTreeNodeSubDesc;
|
SubDesc: TCodeTreeNodeSubDesc;
|
||||||
StartPos, EndPos: integer;
|
StartPos, EndPos: integer;
|
||||||
@ -303,6 +303,10 @@ begin
|
|||||||
Result:=1
|
Result:=1
|
||||||
else if NodeData1.StartPos<NodeData2.StartPos then
|
else if NodeData1.StartPos<NodeData2.StartPos then
|
||||||
Result:=-1
|
Result:=-1
|
||||||
|
else if NodeData1.EndPos>NodeData2.EndPos then
|
||||||
|
Result:=1
|
||||||
|
else if NodeData1.EndPos<NodeData2.EndPos then
|
||||||
|
Result:=-1
|
||||||
else
|
else
|
||||||
Result:=0;
|
Result:=0;
|
||||||
end;
|
end;
|
||||||
@ -1714,6 +1718,7 @@ var
|
|||||||
Code: TCodeBuffer;
|
Code: TCodeBuffer;
|
||||||
NewXY: TPoint;
|
NewXY: TPoint;
|
||||||
OnlyXYChanged: Boolean;
|
OnlyXYChanged: Boolean;
|
||||||
|
CurFollowNode: Boolean;
|
||||||
begin
|
begin
|
||||||
if (FUpdateCount>0)
|
if (FUpdateCount>0)
|
||||||
or (OnlyVisible and ((CurrentPage<>cepCode) or (not IsVisible))) then begin
|
or (OnlyVisible and ((CurrentPage<>cepCode) or (not IsVisible))) then begin
|
||||||
@ -1722,7 +1727,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
Exclude(FFlags,cevCodeRefreshNeeded);
|
Exclude(FFlags,cevCodeRefreshNeeded);
|
||||||
fLastCodeTool:=nil;
|
fLastCodeTool:=nil;
|
||||||
|
OldExpanded:=nil;
|
||||||
try
|
try
|
||||||
Include(FFlags,cevRefreshing);
|
Include(FFlags,cevRefreshing);
|
||||||
|
|
||||||
@ -1768,73 +1773,85 @@ begin
|
|||||||
if not CodeExplorerOptions.FollowCursor then
|
if not CodeExplorerOptions.FollowCursor then
|
||||||
exit;
|
exit;
|
||||||
NewXY:=SrcEdit.CursorTextXY;
|
NewXY:=SrcEdit.CursorTextXY;
|
||||||
|
//debugln(['TCodeExplorerView.RefreshCode ',dbgs(NewXY),' ',dbgs(FLastCodeXY)]);
|
||||||
if ComparePoints(NewXY,FLastCodeXY)=0 then begin
|
if ComparePoints(NewXY,FLastCodeXY)=0 then begin
|
||||||
// still the same cursor position
|
// still the same cursor position
|
||||||
exit;
|
exit;
|
||||||
end;
|
end;
|
||||||
|
FLastCodeXY:=NewXY;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if OnlyXYChanged then begin
|
if OnlyXYChanged then begin
|
||||||
|
SelectCodePosition(Code,FLastCodeXY.X,FLastCodeXY.Y);
|
||||||
end;
|
|
||||||
|
|
||||||
FLastCodeValid:=true;
|
|
||||||
FLastMode:=Mode;
|
|
||||||
fLastCodeOptionsChangeStep:=CodeExplorerOptions.ChangeStep;
|
|
||||||
FLastCodeXY:=SrcEdit.CursorTextXY;
|
|
||||||
// remember the codetools ChangeStep
|
|
||||||
if ACodeTool<>nil then begin
|
|
||||||
FCodeFilename:=ACodeTool.MainFilename;
|
|
||||||
if ACodeTool.Scanner<>nil then
|
|
||||||
FLastCodeChangeStep:=ACodeTool.Scanner.ChangeStep;
|
|
||||||
end else
|
|
||||||
FCodeFilename:='';
|
|
||||||
|
|
||||||
if fCodeSortedForStartPos<>nil then
|
|
||||||
fCodeSortedForStartPos.Clear;
|
|
||||||
|
|
||||||
//DebugLn(['TCodeExplorerView.RefreshCode ',FCodeFilename]);
|
|
||||||
|
|
||||||
// start updating the CodeTreeView
|
|
||||||
CodeTreeview.BeginUpdate;
|
|
||||||
OldExpanded:=TTreeNodeExpandedState.Create(CodeTreeView);
|
|
||||||
|
|
||||||
for c:=low(TCodeExplorerCategory) to high(TCodeExplorerCategory) do
|
|
||||||
fCategoryNodes[c]:=nil;
|
|
||||||
fObserverNode:=nil;
|
|
||||||
for f:=low(TCEObserverCategory) to high(TCEObserverCategory) do
|
|
||||||
fObserverCatNodes[f]:=nil;
|
|
||||||
|
|
||||||
if (ACodeTool=nil) or (ACodeTool.Tree=nil) or (ACodeTool.Tree.Root=nil) then
|
|
||||||
begin
|
|
||||||
CodeTreeview.Items.Clear;
|
|
||||||
end else begin
|
end else begin
|
||||||
CodeTreeview.Items.Clear;
|
|
||||||
CreateIdentifierNodes(ACodeTool,ACodeTool.Tree.Root,nil,nil,true);
|
FLastCodeValid:=true;
|
||||||
if (Mode = cemCategory) and
|
FLastMode:=Mode;
|
||||||
(cecCodeObserver in CodeExplorerOptions.Categories) then
|
fLastCodeOptionsChangeStep:=CodeExplorerOptions.ChangeStep;
|
||||||
CreateObservations(ACodeTool);
|
FLastCodeXY:=SrcEdit.CursorTextXY;
|
||||||
|
// remember the codetools ChangeStep
|
||||||
|
if ACodeTool<>nil then begin
|
||||||
|
FCodeFilename:=ACodeTool.MainFilename;
|
||||||
|
if ACodeTool.Scanner<>nil then
|
||||||
|
FLastCodeChangeStep:=ACodeTool.Scanner.ChangeStep;
|
||||||
|
end else
|
||||||
|
FCodeFilename:='';
|
||||||
|
|
||||||
|
if fCodeSortedForStartPos<>nil then
|
||||||
|
fCodeSortedForStartPos.Clear;
|
||||||
|
|
||||||
|
//DebugLn(['TCodeExplorerView.RefreshCode ',FCodeFilename]);
|
||||||
|
|
||||||
|
CurFollowNode:=CodeExplorerOptions.FollowCursor and (not Active);
|
||||||
|
|
||||||
|
// start updating the CodeTreeView
|
||||||
|
CodeTreeview.BeginUpdate;
|
||||||
|
if not CurFollowNode then
|
||||||
|
OldExpanded:=TTreeNodeExpandedState.Create(CodeTreeView);
|
||||||
|
|
||||||
|
for c:=low(TCodeExplorerCategory) to high(TCodeExplorerCategory) do
|
||||||
|
fCategoryNodes[c]:=nil;
|
||||||
|
fObserverNode:=nil;
|
||||||
|
for f:=low(TCEObserverCategory) to high(TCEObserverCategory) do
|
||||||
|
fObserverCatNodes[f]:=nil;
|
||||||
|
|
||||||
|
if (ACodeTool=nil) or (ACodeTool.Tree=nil) or (ACodeTool.Tree.Root=nil) then
|
||||||
|
begin
|
||||||
|
CodeTreeview.Items.Clear;
|
||||||
|
end else begin
|
||||||
|
CodeTreeview.Items.Clear;
|
||||||
|
CreateIdentifierNodes(ACodeTool,ACodeTool.Tree.Root,nil,nil,true);
|
||||||
|
if (Mode = cemCategory) and
|
||||||
|
(cecCodeObserver in CodeExplorerOptions.Categories) then
|
||||||
|
CreateObservations(ACodeTool);
|
||||||
|
end;
|
||||||
|
|
||||||
|
fSortCodeTool:=ACodeTool;
|
||||||
|
CodeTreeview.CustomSort(@CompareCodeNodes);
|
||||||
|
|
||||||
|
DeleteDuplicates(ACodeTool);
|
||||||
|
|
||||||
|
// restore old expanded state
|
||||||
|
if not CurFollowNode then
|
||||||
|
AutoExpandNodes;
|
||||||
|
|
||||||
|
BuildCodeSortedForStartPos;
|
||||||
|
ClearCTNodes(CodeTreeview);
|
||||||
|
|
||||||
|
ApplyCodeFilter;
|
||||||
|
|
||||||
|
if OldExpanded<>nil then
|
||||||
|
OldExpanded.Apply(CodeTreeView);
|
||||||
|
|
||||||
|
if CurFollowNode then
|
||||||
|
SelectCodePosition(Code,FLastCodeXY.X,FLastCodeXY.Y);
|
||||||
|
|
||||||
|
CodeTreeview.EndUpdate;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// restore old expanded state
|
|
||||||
fSortCodeTool:=ACodeTool;
|
|
||||||
CodeTreeview.CustomSort(@CompareCodeNodes);
|
|
||||||
|
|
||||||
DeleteDuplicates(ACodeTool);
|
|
||||||
AutoExpandNodes;
|
|
||||||
|
|
||||||
BuildCodeSortedForStartPos;
|
|
||||||
ClearCTNodes(CodeTreeview);
|
|
||||||
|
|
||||||
ApplyCodeFilter;
|
|
||||||
|
|
||||||
OldExpanded.Apply(CodeTreeView);
|
|
||||||
OldExpanded.Free;
|
|
||||||
CodeTreeview.EndUpdate;
|
|
||||||
|
|
||||||
finally
|
finally
|
||||||
Exclude(FFlags,cevRefreshing);
|
Exclude(FFlags,cevRefreshing);
|
||||||
|
OldExpanded.Free;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -2020,7 +2037,18 @@ begin
|
|||||||
if fLastCodeTool.CaretToCleanPos(CodePos,CleanPos)<>0 then exit;
|
if fLastCodeTool.CaretToCleanPos(CodePos,CleanPos)<>0 then exit;
|
||||||
TVNode:=FindCodeTVNodeAtCleanPos(CleanPos);
|
TVNode:=FindCodeTVNodeAtCleanPos(CleanPos);
|
||||||
if TVNode=nil then exit;
|
if TVNode=nil then exit;
|
||||||
TVNode.Selected:=true;
|
CodeTreeview.BeginUpdate;
|
||||||
|
CodeTreeview.Options:=CodeTreeview.Options-[tvoAllowMultiselect];
|
||||||
|
if not TVNode.IsVisible then begin
|
||||||
|
// collapse all other and expand only this
|
||||||
|
CodeTreeview.FullCollapse;
|
||||||
|
CodeTreeview.Selected:=TVNode;
|
||||||
|
//debugln(['TCodeExplorerView.SelectCodePosition ',TVNode.Text]);
|
||||||
|
end else begin
|
||||||
|
CodeTreeview.Selected:=TVNode;
|
||||||
|
//debugln(['TCodeExplorerView.SelectCodePosition ',TVNode.Text]);
|
||||||
|
end;
|
||||||
|
CodeTreeview.EndUpdate;
|
||||||
Result:=true;
|
Result:=true;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -2032,32 +2060,27 @@ function TCodeExplorerView.FindCodeTVNodeAtCleanPos(CleanPos: integer
|
|||||||
// if there are several nodes, the one with the shortest range (EndPos-StartPos)
|
// if there are several nodes, the one with the shortest range (EndPos-StartPos)
|
||||||
// is returned.
|
// is returned.
|
||||||
var
|
var
|
||||||
KeyPos: integer;
|
|
||||||
AVLNode: TAvgLvlTreeNode;
|
AVLNode: TAvgLvlTreeNode;
|
||||||
Node: TTreeNode;
|
Node: TTreeNode;
|
||||||
NodeData: TViewNodeData;
|
NodeData: TViewNodeData;
|
||||||
BestData: TViewNodeData;
|
|
||||||
begin
|
begin
|
||||||
Result:=nil;
|
Result:=nil;
|
||||||
if (fLastCodeTool=nil) or (not FLastCodeValid) or (CodeTreeview=nil)
|
if (fLastCodeTool=nil) or (not FLastCodeValid) or (CodeTreeview=nil)
|
||||||
or (fCodeSortedForStartPos=nil) then exit;
|
or (fCodeSortedForStartPos=nil) then exit;
|
||||||
KeyPos:=CleanPos;
|
// find nearest node in tree
|
||||||
AVLNode:=fCodeSortedForStartPos.FindLeftMostKey(@KeyPos,
|
|
||||||
TListSortCompare(@CompareStartPosWithViewNodeData));
|
AVLNode:=fCodeSortedForStartPos.FindLowest;
|
||||||
// find the shortest
|
|
||||||
BestData:=nil;
|
|
||||||
Result:=nil;
|
|
||||||
while AVLNode<>nil do begin
|
while AVLNode<>nil do begin
|
||||||
Node:=TTreeNode(AVLNode.Data);
|
Node:=TTreeNode(AVLNode.Data);
|
||||||
if TObject(Node.Data) is TViewNodeData then begin
|
NodeData:=TViewNodeData(Node.Data);
|
||||||
NodeData:=TViewNodeData(Node.Data);
|
//debugln(['TCodeExplorerView.FindCodeTVNodeAtCleanPos Node ',NodeData.StartPos,'-',NodeData.EndPos,' ',Node.Text,' ',CleanPos]);
|
||||||
if (BestData=nil)
|
if NodeData.StartPos>CleanPos then exit;
|
||||||
or ((BestData.StartPos<=NodeData.StartPos)
|
if NodeData.EndPos>=CleanPos then begin
|
||||||
and (BestData.EndPos>=NodeData.EndPos))
|
if (Result=nil)
|
||||||
then begin
|
or (NodeData.EndPos-NodeData.StartPos
|
||||||
|
< TViewNodeData(Result.Data).EndPos-TViewNodeData(Result.Data).StartPos)
|
||||||
|
then
|
||||||
Result:=Node;
|
Result:=Node;
|
||||||
BestData:=TViewNodeData(Node.Data);
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
AVLNode:=fCodeSortedForStartPos.FindSuccessor(AVLNode);
|
AVLNode:=fCodeSortedForStartPos.FindSuccessor(AVLNode);
|
||||||
end;
|
end;
|
||||||
@ -2074,7 +2097,8 @@ begin
|
|||||||
TVNode:=CodeTreeview.Items.GetFirstNode;
|
TVNode:=CodeTreeview.Items.GetFirstNode;
|
||||||
while TVNode<>nil do begin
|
while TVNode<>nil do begin
|
||||||
NodeData:=TViewNodeData(TVNode.Data);
|
NodeData:=TViewNodeData(TVNode.Data);
|
||||||
if (NodeData<>nil) and (NodeData.StartPos>0) then begin
|
if (NodeData<>nil) and (NodeData.StartPos>0)
|
||||||
|
and (NodeData.EndPos>=NodeData.StartPos) then begin
|
||||||
if fCodeSortedForStartPos=nil then
|
if fCodeSortedForStartPos=nil then
|
||||||
fCodeSortedForStartPos:=
|
fCodeSortedForStartPos:=
|
||||||
TAvgLvlTree.Create(TListSortCompare(@CompareViewNodeDataStartPos));
|
TAvgLvlTree.Create(TListSortCompare(@CompareViewNodeDataStartPos));
|
||||||
|
|||||||
@ -85,6 +85,5 @@ inherited CodeExplorerUpdateOptionsFrame: TCodeExplorerUpdateOptionsFrame
|
|||||||
ParentShowHint = False
|
ParentShowHint = False
|
||||||
ShowHint = True
|
ShowHint = True
|
||||||
TabOrder = 2
|
TabOrder = 2
|
||||||
Visible = False
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user