IDE: code explorer: follow cursor

git-svn-id: trunk@26492 -
This commit is contained in:
mattias 2010-07-06 19:00:06 +00:00
parent 1317f884b2
commit 7b45c23d5e
2 changed files with 100 additions and 77 deletions

View File

@ -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));

View File

@ -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