42
42
Classes, SysUtils, types, LCLProc, LCLType, Forms, Controls, Graphics,
43
43
Dialogs, Buttons, ComCtrls, Menus, AvgLvlTree, StdCtrls, ExtCtrls,
45
BasicCodeTools, CustomCodeTool, CodeToolManager, CodeAtom, CodeCache,
46
CodeTree, KeywordFuncLists, FindDeclarationTool, DirectivesTree,
45
FileProcs, BasicCodeTools, CustomCodeTool, CodeToolManager, CodeAtom,
46
CodeCache, CodeTree, KeywordFuncLists, FindDeclarationTool, DirectivesTree,
49
49
LazIDEIntf, IDECommands, MenuIntf, SrcEditorIntf,
128
128
MainNotebook: TPageControl;
129
129
MenuItem1: TMenuItem;
130
130
CodeTreeviewButtonPanel: TPanel;
131
OptionsSpeedButton: TSpeedButton;
132
RefreshSpeedButton: TSpeedButton;
133
ModeSpeedButton: TSpeedButton;
131
CodeOptionsSpeedButton: TSpeedButton;
132
CodeRefreshSpeedButton: TSpeedButton;
133
CodeModeSpeedButton: TSpeedButton;
134
DirOptionsSpeedButton: TSpeedButton;
135
DirRefreshSpeedButton: TSpeedButton;
134
136
TreePopupmenu: TPopupMenu;
135
137
procedure CodeExplorerViewCreate(Sender: TObject);
136
138
procedure CodeExplorerViewDestroy(Sender: TObject);
139
procedure CodeFilterEditExit(Sender: TObject);
137
140
procedure CodeTreeviewDblClick(Sender: TObject);
138
141
procedure CodeTreeviewDeletion(Sender: TObject; Node: TTreeNode);
139
142
procedure CodeTreeviewKeyUp(Sender: TObject; var Key: Word;
145
148
procedure DirectivesTreeViewKeyUp(Sender: TObject; var Key: Word;
146
149
Shift: TShiftState);
147
150
procedure IdleTimer1Timer(Sender: TObject);
148
procedure JumpToMenuitemClick(Sender: TObject);
151
procedure JumpToMenuItemClick(Sender: TObject);
152
procedure JumpToImplementationMenuItemClick(Sender: TObject);
153
procedure ShowSrcEditPosMenuItemClick(Sender: TObject);
149
154
procedure MainNotebookPageChanged(Sender: TObject);
150
procedure ModeSpeedButtonClick(Sender: TObject);
151
procedure OptionsSpeedButtonClick(Sender: TObject);
152
procedure RefreshMenuitemClick(Sender: TObject);
153
procedure RefreshSpeedButtonClick(Sender: TObject);
155
procedure CodeModeSpeedButtonClick(Sender: TObject);
156
procedure CodeOptionsSpeedButtonClick(Sender: TObject);
157
procedure RefreshMenuItemClick(Sender: TObject);
158
procedure CodeRefreshSpeedButtonClick(Sender: TObject);
154
159
procedure RenameMenuItemClick(Sender: TObject);
155
160
procedure TreePopupmenuPopup(Sender: TObject);
156
161
procedure OnUserInput(Sender: TObject; Msg: Cardinal);
163
fCategoryNodes: array[TCodeExplorerCategory] of TTreeNode;
158
164
FCodeFilename: string;
159
fCategoryNodes: array[TCodeExplorerCategory] of TTreeNode;
160
fObserverNode: TTreeNode;
161
fObserverCatNodes: array[TCEObserverCategory] of TTreeNode;
162
fObserverCatOverflow: array[TCEObserverCategory] of boolean;
163
165
FDirectivesFilename: string;
164
166
FFlags: TCodeExplorerViewFlags;
167
FLastCodeChangeStep: integer;
165
168
FLastCodeFilter: string;
166
FLastCodeChangeStep: integer;
167
169
fLastCodeOptionsChangeStep: integer;
170
FLastCodeValid: boolean;
172
FLastCode: TCodeBuffer;
173
FLastDirectivesChangeStep: integer;
168
174
FLastDirectivesFilter: string;
169
FLastDirectivesChangeStep: integer;
175
FLastMode: TCodeExplorerMode;
170
176
FMode: TCodeExplorerMode;
171
FLastMode: TCodeExplorerMode;
172
FLastCodeValid: boolean;
177
fObserverCatNodes: array[TCEObserverCategory] of TTreeNode;
178
fObserverCatOverflow: array[TCEObserverCategory] of boolean;
179
fObserverNode: TTreeNode;
180
fSurroundingNode: TTreeNode;
174
181
FOnGetDirectivesTree: TOnGetDirectivesTree;
175
182
FOnJumpToCode: TOnJumpToCode;
176
183
FOnShowOptions: TNotifyEvent;
184
fSortCodeTool: TCodeTool;
177
185
FUpdateCount: integer;
178
fSortCodeTool: TCodeTool;
179
186
ImgIDClass: Integer;
180
187
ImgIDConst: Integer;
181
188
ImgIDSection: Integer;
287
304
TViewNodeData = class
289
CTNode: TCodeTreeNode; // only valid during update, other times it is nil
306
CTNode: TCodeTreeNode; // only valid during update, at other times it is nil
290
307
Desc: TCodeTreeNodeDesc;
291
308
SubDesc: TCodeTreeNodeSubDesc;
292
309
StartPos, EndPos: integer;
293
constructor Create(CodeNode: TCodeTreeNode);
312
ImplementationNode: TViewNodeData;
313
SortChildren: boolean; // sort for TVNode text (optional) and StartPos, EndPos
314
constructor Create(CodeNode: TCodeTreeNode; SortTheChildren: boolean = true);
315
destructor Destroy; override;
316
procedure CreateParams(ACodeTool: TCodeTool);
296
319
function CompareViewNodeDataStartPos(Node1, Node2: TTreeNode): integer;
351
function CompareViewNodePathsAndParams(NodeData1, NodeData2: Pointer): integer;
353
Node1: TViewNodeData absolute NodeData1;
354
Node2: TViewNodeData absolute NodeData2;
356
Result:=SysUtils.CompareText(Node1.Path,Node2.Path);
357
if Result<>0 then exit;
358
Result:=SysUtils.CompareText(Node1.Params,Node2.Params);
361
function CompareViewNodePaths(NodeData1, NodeData2: Pointer): integer;
363
Node1: TViewNodeData absolute NodeData1;
364
Node2: TViewNodeData absolute NodeData2;
366
Result:=SysUtils.CompareText(Node1.Path,Node2.Path);
328
369
procedure RegisterStandardCodeExplorerMenuItems;
332
373
CodeExplorerMenuRoot:=RegisterIDEMenuRoot(CodeExplorerMenuRootName);
333
374
Path:=CodeExplorerMenuRoot.Name;
334
CEJumpToIDEMenuCommand:=RegisterIDEMenuCommand(Path, 'Jump to', lisMenuJumpTo
336
CERefreshIDEMenuCommand:=RegisterIDEMenuCommand(Path, 'Refresh',
338
CERenameIDEMenuCommand:=RegisterIDEMenuCommand(Path, 'Rename', lisFRIRename);
375
CEJumpToIDEMenuCommand:=RegisterIDEMenuCommand(Path, 'Jump to', lisMenuJumpTo);
376
CEJumpToImplementationIDEMenuCommand:=RegisterIDEMenuCommand(Path,
377
'Jump to implementation', lisMenuJumpToImplementation);
378
CEShowSrcEditPosIDEMenuCommand:=RegisterIDEMenuCommand(Path, 'Show position of source editor',
379
lisShowPositionOfSourceEditor);
380
CERefreshIDEMenuCommand:=RegisterIDEMenuCommand(Path, 'Refresh', dlgUnitDepRefresh);
381
CERenameIDEMenuCommand:=RegisterIDEMenuCommand(Path, 'Rename', lisRename);
341
384
function GetToDoComment(const Src: string; CommentStartPos,
381
424
{ TViewNodeData }
383
constructor TViewNodeData.Create(CodeNode: TCodeTreeNode);
426
constructor TViewNodeData.Create(CodeNode: TCodeTreeNode;
427
SortTheChildren: boolean);
385
429
CTNode:=CodeNode;
386
430
Desc:=CodeNode.Desc;
387
431
SubDesc:=CodeNode.SubDesc;
388
432
StartPos:=CodeNode.StartPos;
389
433
EndPos:=CodeNode.EndPos;
434
SortChildren:=SortTheChildren;
437
destructor TViewNodeData.Destroy;
439
FreeAndNil(ImplementationNode);
443
procedure TViewNodeData.CreateParams(ACodeTool: TCodeTool);
445
if Params<>'' then exit;
446
if CTNode.Desc=ctnProcedure then
447
Params:=ACodeTool.ExtractProcHead(CTNode,
448
[phpWithoutClassKeyword,phpWithoutClassName,phpWithoutName,phpWithoutSemicolon]);
392
453
{ TCodeExplorerView }
402
463
MainNotebook.ActivePage:=CodePage;
404
RefreshSpeedButton.Hint:=dlgUnitDepRefresh;
405
OptionsSpeedButton.Hint:=dlgFROpts;
465
CodePage.Caption:=lisCode;
466
CodeRefreshSpeedButton.Hint:=dlgUnitDepRefresh;
467
CodeOptionsSpeedButton.Hint:=dlgFROpts;
406
468
CodeFilterEdit.Text:=lisCEFilter;
407
CodePage.Caption:=lisCode;
469
DirectivesPage.Caption:=lisDirectives;
408
470
DirectivesFilterEdit.Text:=lisCEFilter;
409
DirectivesPage.Caption:=lisDirectives;
471
DirRefreshSpeedButton.Hint:=dlgUnitDepRefresh;
472
DirOptionsSpeedButton.Hint:=dlgFROpts;
412
RefreshSpeedButton.LoadGlyphFromLazarusResource('laz_refresh');
413
OptionsSpeedButton.LoadGlyphFromLazarusResource('menu_environment_options');
474
CodeRefreshSpeedButton.LoadGlyphFromLazarusResource('laz_refresh');
475
CodeOptionsSpeedButton.LoadGlyphFromLazarusResource('menu_environment_options');
476
DirRefreshSpeedButton.LoadGlyphFromLazarusResource('laz_refresh');
477
DirOptionsSpeedButton.LoadGlyphFromLazarusResource('menu_environment_options');
415
479
ImgIDDefault := Imagelist1.AddLazarusResource('ce_default');
416
480
ImgIDProgram := Imagelist1.AddLazarusResource('ce_program');
436
500
CodeExplorerMenuRoot.MenuItem:=TreePopupMenu.Items;
437
501
//CodeExplorerMenuRoot.Items.WriteDebugReport(' ');
439
CEJumpToIDEMenuCommand.OnClick:=@JumpToMenuitemCLICK;
440
CERefreshIDEMenuCommand.OnClick:=@RefreshMenuitemCLICK;
503
CEJumpToIDEMenuCommand.OnClick:=@JumpToMenuItemClick;
504
CEJumpToImplementationIDEMenuCommand.OnClick:=@JumpToImplementationMenuItemClick;
505
CEShowSrcEditPosIDEMenuCommand.OnClick:=@ShowSrcEditPosMenuItemClick;
506
CERefreshIDEMenuCommand.OnClick:=@RefreshMenuItemClick;
441
507
CERenameIDEMenuCommand.OnClick:=@RenameMenuItemClick;
509
fNodesWithPath:=TAvgLvlTree.Create(@CompareViewNodePathsAndParams);
443
511
Application.AddOnUserInputHandler(@OnUserInput);
446
514
procedure TCodeExplorerView.CodeExplorerViewDestroy(Sender: TObject);
448
516
//debugln('TCodeExplorerView.CodeExplorerViewDestroy');
518
FreeAndNil(fNodesWithPath);
519
FreeAndNil(fCodeSortedForStartPos);
520
if CodeExplorerView=Self then
521
CodeExplorerView:=nil;
524
procedure TCodeExplorerView.CodeFilterEditExit(Sender: TObject);
526
if CodeFilterEdit.Text='' then
527
CodeFilterEdit.Text:=lisCEFilter;
451
530
procedure TCodeExplorerView.CodeTreeviewDblClick(Sender: TObject);
505
584
and (fsModal in Screen.ActiveCustomForm.FormState) then
507
586
if not IsVisible then exit;
587
Exclude(FFlags,cevCheckOnIdle);
590
cepCode: if (CurrentPage<>cepCode) or CodeTreeview.Focused then exit;
591
cepDirectives: if (CurrentPage<>cepDirectives) or DirectivesTreeView.Focused then exit;
512
procedure TCodeExplorerView.JumpToMenuitemCLICK(Sender: TObject);
596
procedure TCodeExplorerView.JumpToMenuItemClick(Sender: TObject);
598
JumpToSelection(false);
601
procedure TCodeExplorerView.JumpToImplementationMenuItemClick(Sender: TObject);
603
JumpToSelection(true);
606
procedure TCodeExplorerView.ShowSrcEditPosMenuItemClick(Sender: TObject);
608
SelectSourceEditorNode;
517
611
procedure TCodeExplorerView.MainNotebookPageChanged(Sender: TObject);
762
// don't show modifier nodes
763
if CodeNode.Desc in [ctnIdentifier,ctnRangedArrayType,
893
if CodeNode.Desc in [ctnConstant,ctnIdentifier,ctnRangedArrayType,
764
894
ctnOpenArrayType,ctnOfConstType,ctnRangeType,ctnTypeType,ctnFileType,
765
ctnVariantType,ctnEnumerationType,ctnSetType,ctnProcedureType]
770
if CodeNode.Desc=ctnEndPoint then
895
ctnVariantType,ctnSetType,ctnProcedureType]
901
// show enums, but not the brackets
902
if CodeNode.Desc=ctnEnumerationType then
905
// don't show special nodes
906
if CodeNode.Desc in [ctnEndPoint] then
773
909
// don't show class visibility section nodes
774
if (CodeNode.Desc in AllClassSections) then begin
910
if (CodeNode.Desc in AllClassSections) then
778
913
if Mode=cemCategory then begin
779
914
// don't show method bodies
783
918
ShowChilds:=false;
921
// don't show single hint modifiers
922
if (CodeNode.Desc = ctnHintModifier) and (CurParentViewNode = nil) then
786
928
// category mode: put nodes in categories
787
929
Category:=cecNone;
789
931
and ((CodeNode.Parent=nil)
790
or (CodeNode.Parent.Desc in AllCodeSections)
791
or (CodeNode.Parent.Parent=nil)
792
or (CodeNode.Parent.Parent.Desc in AllCodeSections)) then
932
or (CodeNode.Parent.Desc in AllCodeSections)
933
or (CodeNode.Parent.Parent=nil)
934
or (CodeNode.Parent.Parent.Desc in AllCodeSections)) then
794
936
// top level definition
795
937
case CodeNode.Desc of
796
ctnUsesSection: Category:=cecUses;
938
ctnUseUnit: Category:=cecUses;
797
939
ctnTypeDefinition,ctnGenericType: Category:=cecTypes;
798
940
ctnVarDefinition: Category:=cecVariables;
799
ctnConstDefinition: Category:=cecConstants;
941
ctnConstDefinition,ctnEnumIdentifier: Category:=cecConstants;
800
942
ctnProcedure: Category:=cecProcedures;
801
943
ctnProperty: Category:=cecProperties;
809
951
NodeText:=CodeExplorerLocalizedString(Category);
810
952
NodeImageIndex:=GetCodeNodeImage(ACodeTool,CodeNode.Parent);
811
953
fCategoryNodes[Category]:=CodeTreeview.Items.AddChildObject(nil,
813
955
fCategoryNodes[Category].ImageIndex:=NodeImageIndex;
814
956
fCategoryNodes[Category].SelectedIndex:=NodeImageIndex;
816
ParentViewNode:=fCategoryNodes[Category];
958
if (CurParentViewNode=nil) then
959
CurParentViewNode:=fCategoryNodes[Category];
817
960
InFrontViewNode:=nil;
822
end else if (CodeNode.Parent<>nil)
823
and (CodeNode.Parent.Desc in (AllClassSections+AllClassInterfaces+[ctnRecordType]))
825
// show class, interface and record nodes
966
// not a top level node
830
//DebugLn(['TCodeExplorerView.CreateNodes ',CodeNode.DescAsString,' ShowNode=',ShowNode,' ShowChilds=',ShowChilds]);
968
//DebugLn(['TCodeExplorerView.CreateIdentifierNodes ',CodeNode.DescAsString,' ShowNode=',ShowNode,' ShowChilds=',ShowChilds]);
833
971
if ShowNode then begin
972
// add a node to the TTreeView
834
973
NodeData:=TViewNodeData.Create(CodeNode);
974
CreateNodePath(ACodeTool,NodeData);
835
975
NodeText:=GetCodeNodeDescription(ACodeTool,CodeNode);
836
976
NodeImageIndex:=GetCodeNodeImage(ACodeTool,CodeNode);
977
//if NodeText='TCodeExplorerView' then
978
// debugln(['TCodeExplorerView.CreateIdentifierNodes CodeNode=',CodeNode.DescAsString,' NodeText="',NodeText,'" Category=',dbgs(Category),' InFrontViewNode=',InFrontViewNode<>nil,' CurParentViewNode=',CurParentViewNode<>nil]);
837
979
if InFrontViewNode<>nil then
838
980
ViewNode:=CodeTreeview.Items.InsertObjectBehind(
839
981
InFrontViewNode,NodeText,NodeData)
840
else if ParentViewNode<>nil then
982
else if CurParentViewNode<>nil then
841
983
ViewNode:=CodeTreeview.Items.AddChildObject(
842
ParentViewNode,NodeText,NodeData)
984
CurParentViewNode,NodeText,NodeData)
844
986
ViewNode:=CodeTreeview.Items.AddObject(nil,NodeText,NodeData);
845
987
ViewNode.ImageIndex:=NodeImageIndex;
846
988
ViewNode.SelectedIndex:=NodeImageIndex;
847
989
InFrontViewNode:=ViewNode;
849
ViewNode:=ParentViewNode;
991
// do not add a node to the TTreeView
992
ViewNode:=CurParentViewNode;
993
AddImplementationNode(ACodeTool,CodeNode);
851
995
if ShowChilds then
852
996
CreateIdentifierNodes(ACodeTool,CodeNode.FirstChild,ViewNode,nil,true);
1514
1657
until p>SrcLen;
1660
procedure TCodeExplorerView.CreateSurrounding(Tool: TCodeTool);
1662
function CTNodeIsEnclosing(CTNode: TCodeTreeNode; p: integer): boolean;
1664
NextCTNode: TCodeTreeNode;
1667
if (p<CTNode.StartPos) or (p>CTNode.EndPos) then exit;
1668
if (p=CTNode.EndPos) then begin
1669
NextCTNode:=CTNode.NextSkipChilds;
1670
if (NextCTNode<>nil) and (NextCTNode.StartPos<=p) then exit;
1675
procedure CreateSubNodes(ParentTVNode: TTreeNode; CTNode: TCodeTreeNode;
1678
ChildCTNode: TCodeTreeNode;
1679
ChildData: TViewNodeData;
1680
ChildTVNode: TTreeNode;
1683
CurParentTVNode: TTreeNode;
1685
ChildCTNode:=CTNode.FirstChild;
1686
while ChildCTNode<>nil do
1690
if CTNodeIsEnclosing(ChildCTNode,p) then begin
1693
if ChildCTNode.Desc in AllClasses then
1695
end else if (CTNode.Desc=ctnProcedure)
1696
and (ChildCTNode.Desc<>ctnProcedureHead) then begin
1700
CurParentTVNode:=ParentTVNode;
1703
ChildData:=TViewNodeData.Create(ChildCTNode,false);
1704
ChildTVNode:=CodeTreeview.Items.AddChildObject(
1705
ParentTVNode,GetCodeNodeDescription(Tool,ChildCTNode),ChildData);
1706
ChildTVNode.ImageIndex:=GetCodeNodeImage(Tool,ChildCTNode);
1707
ChildTVNode.SelectedIndex:=ChildTVNode.ImageIndex;
1708
CurParentTVNode:=ChildTVNode;
1713
CreateSubNodes(CurParentTVNode,ChildCTNode,p);
1714
if ChildTVNode<>nil then
1715
ChildTVNode.Expanded:=true;
1717
ChildCTNode:=ChildCTNode.NextBrother;
1722
CodeNode: TCodeTreeNode;
1723
Data: TViewNodeData;
1725
CurPos: TCodeXYPosition;
1728
if fSurroundingNode = nil then
1730
fSurroundingNode:=CodeTreeview.Items.Add(nil, lisCESurrounding);
1731
Data:=TViewNodeData.Create(Tool.Tree.Root,false);
1733
Data.StartPos:=Tool.SrcLen;
1734
fSurroundingNode.Data:=Data;
1735
fSurroundingNode.ImageIndex:=ImgIDSection;
1736
fSurroundingNode.SelectedIndex:=ImgIDSection;
1739
CurPos.Code:=FLastCode;
1740
CurPos.X:=FLastCodeXY.X;
1741
CurPos.Y:=FLastCodeXY.Y;
1742
fLastCodeTool.CaretToCleanPos(CurPos,p);
1744
// add all top lvl sections
1745
CodeNode:=Tool.Tree.Root;
1746
while CodeNode<>nil do begin
1747
Data:=TViewNodeData.Create(CodeNode,false);
1748
TVNode:=CodeTreeview.Items.AddChildObject(
1749
fSurroundingNode,GetCodeNodeDescription(Tool,CodeNode),Data);
1750
TVNode.ImageIndex:=GetCodeNodeImage(Tool,CodeNode);
1751
TVNode.SelectedIndex:=TVNode.ImageIndex;
1752
if CTNodeIsEnclosing(CodeNode,p) then
1753
CreateSubNodes(TVNode,CodeNode,p);
1754
TVNode.Expanded:=true;
1756
CodeNode:=CodeNode.NextBrother;
1758
fSurroundingNode.Expanded:=true;
1761
procedure TCodeExplorerView.DeleteTVNode(TVNode: TTreeNode);
1763
c: TCodeExplorerCategory;
1764
oc: TCEObserverCategory;
1766
if TVNode=nil then exit;
1767
if TVNode.Data<>nil then begin
1768
if (TObject(TVNode.Data) is TViewNodeData) and (fCodeSortedForStartPos<>nil)
1770
fCodeSortedForStartPos.Remove(TVNode);
1771
TObject(TVNode.Data).Free;
1774
if TVNode.Parent=nil then begin
1775
if TVNode=fObserverNode then
1777
else if TVNode=fSurroundingNode then
1778
fSurroundingNode:=nil
1780
for c:=low(fCategoryNodes) to high(fCategoryNodes) do
1781
if fCategoryNodes[c]=TVNode then
1782
fCategoryNodes[c]:=nil;
1784
end else if TVNode=fObserverNode then begin
1785
for oc:=low(fObserverCatNodes) to high(fObserverCatNodes) do
1786
if fObserverCatNodes[oc]=TVNode then
1787
fObserverCatNodes[oc]:=nil;
1517
1792
procedure TCodeExplorerView.SetCodeFilter(const AValue: string);
1519
1794
if CodeFilter=AValue then exit;
1568
1843
ANode: TTreeNode;
1569
1844
TheFilter: String;
1571
TheFilter:=CodeFilterEdit.Text;
1846
TheFilter:=GetCodeFilter;
1847
//DebugLn(['TCodeExplorerView.ApplyCodeFilter ====================="',TheFilter,'"']);
1572
1848
FLastCodeFilter:=TheFilter;
1573
1849
CodeTreeview.BeginUpdate;
1574
CodeTreeview.Options:=CodeTreeview.Options+[tvoAllowMultiselect];
1575
//DebugLn(['TCodeExplorerView.ApplyCodeFilter =====================']);
1576
1850
ANode:=CodeTreeview.Items.GetFirstNode;
1577
1851
while ANode<>nil do begin
1578
1852
FilterNode(ANode,TheFilter);
1685
1954
TVNode:=CodeTreeview.Items.GetFirstNode;
1686
1955
while TVNode<>nil do begin
1687
1956
NextTVNode:=TVNode.GetNext;
1689
DeleteNextNode:=false;
1690
if (NextTVNode<>nil)
1691
and (CompareTextIgnoringSpace(TVNode.Text,NextTVNode.Text,false)=0) then
1957
if NextTVNode=nil then break;
1958
if (TVNode.Parent<>nil) and (NextTVNode.Parent=TVNode.Parent) then
1693
Data:=TViewNodeData(TVNode.Data);
1694
NextData:=TViewNodeData(NextTVNode.Data);
1695
if IsForward(Data) then
1697
if IsForward(NextData) then
1698
DeleteNextNode:=true;
1700
if DeleteNextNode then begin
1701
TViewNodeData(NextTVNode.Data).Free;
1702
NextTVNode.Data:=nil;
1705
end else if DeleteNode then begin
1706
TViewNodeData(TVNode.Data).Free;
1961
DeleteNextNode:=false;
1962
if (CompareTextIgnoringSpace(TVNode.Text,NextTVNode.Text,false)=0) then
1964
Data:=TViewNodeData(TVNode.Data);
1965
NextData:=TViewNodeData(NextTVNode.Data);
1966
if IsForward(Data) then
1968
if IsForward(NextData) then
1969
DeleteNextNode:=true;
1971
if DeleteNextNode then begin
1972
DeleteTVNode(NextTVNode);
1974
end else if DeleteNode then begin
1975
NextTVNode:=TVNode.GetNextSkipChildren;
1976
DeleteTVNode(TVNode);
1710
1979
TVNode:=NextTVNode;
1818
2095
fObserverNode:=nil;
1819
2096
for f:=low(TCEObserverCategory) to high(TCEObserverCategory) do
1820
2097
fObserverCatNodes[f]:=nil;
2098
fSurroundingNode:=nil;
1822
if (ACodeTool=nil) or (ACodeTool.Tree=nil) or (ACodeTool.Tree.Root=nil) then
1824
CodeTreeview.Items.Clear;
1826
CodeTreeview.Items.Clear;
2100
CodeTreeview.Items.Clear;
2101
if (ACodeTool<>nil) and (ACodeTool.Tree<>nil) and (ACodeTool.Tree.Root<>nil)
1827
2103
CreateIdentifierNodes(ACodeTool,ACodeTool.Tree.Root,nil,nil,true);
1828
if (Mode = cemCategory) and
1829
(cecCodeObserver in CodeExplorerOptions.Categories) then
1830
CreateObservations(ACodeTool);
2104
if (Mode = cemCategory) then
2106
if (cecCodeObserver in CodeExplorerOptions.Categories) then
2107
CreateObservations(ACodeTool);
2108
if (cecSurrounding in CodeExplorerOptions.Categories) then
2109
CreateSurrounding(ACodeTool);
1833
2114
fSortCodeTool:=ACodeTool;
1834
CodeTreeview.CustomSort(@CompareCodeNodes);
2115
TVNode:=CodeTreeview.Items.GetFirstNode;
2116
while TVNode<>nil do begin
2117
if (TVNode.GetFirstChild<>nil)
2118
and (TObject(TVNode.Data) is TViewNodeData)
2119
and TViewNodeData(TVNode.Data).SortChildren then begin
2120
TVNode.CustomSort(@CompareCodeNodes);
2122
TVNode:=TVNode.GetNext;
1836
2125
DeleteDuplicates(ACodeTool);
1840
2129
AutoExpandNodes;
1842
2131
BuildCodeSortedForStartPos;
2132
// clear references to the TCodeTreeNode to avoid dangling pointers
1843
2133
ClearCTNodes(CodeTreeview);
1845
2135
ApplyCodeFilter;
1847
2137
if OldExpanded<>nil then
1848
OldExpanded.Apply(CodeTreeView);
2138
OldExpanded.Apply(CodeTreeView,false);
1850
2140
if CurFollowNode then
1851
2141
SelectCodePosition(Code,FLastCodeXY.X,FLastCodeXY.Y);
1853
2143
CodeTreeview.EndUpdate;
2145
Caption := lisMenuViewCodeExplorer + ' - ' + ExtractFileName(FCodeFilename);
2146
if HostDockSite <> nil then
2147
HostDockSite.UpdateDockCaption();
1856
2149
Exclude(FFlags,cevRefreshing);
1857
2150
OldExpanded.Free;
2037
2334
if CurrentPage=cepCode then begin
2038
2335
if FLastCodeValid and (fLastCodeTool<>nil) then begin
2039
2336
CodePos:=CodeXYPosition(X,Y,CodeBuf);
2337
CodeBuf.LineColToPosition(Y,X,CleanPos);
2338
//debugln(['TCodeExplorerView.SelectCodePosition Code ',ExtractFileName(CodeBuf.Filename),' y=',y,' x=',x,' CleanPos=',CleanPos,' ',dbgstr(copy(CodeBuf.Source,CleanPos-20,20)),'|',dbgstr(copy(CodeBuf.Source,CleanPos,20))]);
2040
2339
if fLastCodeTool.CaretToCleanPos(CodePos,CleanPos)<>0 then exit;
2340
//debugln(['TCodeExplorerView.SelectCodePosition CleanSrc ',ExtractFileName(CodeBuf.Filename),' y=',y,' x=',x,' Tool=',ExtractFileName(fLastCodeTool.MainFilename),' ',dbgstr(copy(fLastCodeTool.Src,CleanPos-20,20)),'|',dbgstr(copy(fLastCodeTool.Src,CleanPos,20))]);
2041
2341
TVNode:=FindCodeTVNodeAtCleanPos(CleanPos);
2042
2342
if TVNode=nil then exit;
2343
//debugln(['TCodeExplorerView.SelectCodePosition ',TVNode.Text]);
2043
2344
CodeTreeview.BeginUpdate;
2044
2345
CodeTreeview.Options:=CodeTreeview.Options-[tvoAllowMultiselect];
2045
2346
if not TVNode.IsVisible then begin
2051
2352
CodeTreeview.Selected:=TVNode;
2052
2353
//debugln(['TCodeExplorerView.SelectCodePosition ',TVNode.Text]);
2355
//debugln(['TCodeExplorerView.SelectCodePosition TVNode=',TVNode.Text,' Selected=',CodeTreeview.Selected=TVNode]);
2054
2356
CodeTreeview.EndUpdate;
2060
function TCodeExplorerView.FindCodeTVNodeAtCleanPos(CleanPos: integer
2362
function TCodeExplorerView.FindCodeTVNodeAtCleanPos(CleanPos: integer): TTreeNode;
2062
2363
// find TTreeNode in CodeTreeView containing the codetools clean position
2063
2364
// if there are several nodes, the one with the shortest range (EndPos-StartPos)
2064
2365
// is returned.
2368
BestStartPos, BestEndPos: integer;
2370
procedure Check(TVNode: TTreeNode; NodeData: TViewNodeData);
2372
if NodeData=nil then exit;
2373
if (NodeData.StartPos>CleanPos) or (NodeData.EndPos<CleanPos) then exit;
2374
//debugln(['FindCodeTVNodeAtCleanPos.Check TVNode="',TVNode.Text,'" NodeData="',dbgstr(copy(fLastCodeTool.Src,NodeData.StartPos,40)),'"']);
2375
if (Best<>nil) then begin
2376
if (BestEndPos=CleanPos) and (NodeData.EndPos>CleanPos) then begin
2377
// for example a,|b then b is better
2378
end else if BestEndPos-BestStartPos > NodeData.EndPos-NodeData.StartPos then begin
2379
// smaller range is better
2384
BestStartPos:=NodeData.StartPos;
2385
BestEndPos:=NodeData.EndPos;
2066
2389
AVLNode: TAvgLvlTreeNode;
2067
2390
Node: TTreeNode;
2068
2391
NodeData: TViewNodeData;
2071
2394
if (fLastCodeTool=nil) or (not FLastCodeValid) or (CodeTreeview=nil)
2072
2395
or (fCodeSortedForStartPos=nil) then exit;
2073
2397
// find nearest node in tree
2075
2401
AVLNode:=fCodeSortedForStartPos.FindLowest;
2076
2402
while AVLNode<>nil do begin
2077
2403
Node:=TTreeNode(AVLNode.Data);
2078
2404
NodeData:=TViewNodeData(Node.Data);
2079
2405
//debugln(['TCodeExplorerView.FindCodeTVNodeAtCleanPos Node ',NodeData.StartPos,'-',NodeData.EndPos,' ',Node.Text,' ',CleanPos]);
2080
if NodeData.StartPos>CleanPos then exit;
2081
if NodeData.EndPos>=CleanPos then begin
2083
or (NodeData.EndPos-NodeData.StartPos
2084
< TViewNodeData(Result.Data).EndPos-TViewNodeData(Result.Data).StartPos)
2406
Check(Node,NodeData);
2407
Check(Node,NodeData.ImplementationNode);
2088
2408
AVLNode:=fCodeSortedForStartPos.FindSuccessor(AVLNode);
2092
2413
procedure TCodeExplorerView.BuildCodeSortedForStartPos;
2147
2478
const TheFilter: string): boolean;
2149
2480
ChildNode: TTreeNode;
2150
HasVisibleChilds: Boolean;
2481
NextNode: TTreeNode;
2152
2483
if ANode=nil then exit(false);
2153
2484
ChildNode:=ANode.GetFirstChild;
2154
HasVisibleChilds:=false;
2155
2485
while ChildNode<>nil do begin
2156
if FilterNode(ChildNode,TheFilter) then
2157
HasVisibleChilds:=true;
2158
ChildNode:=ChildNode.GetNextSibling;
2486
NextNode:=ChildNode.GetNextSibling;
2487
FilterNode(ChildNode,TheFilter);
2488
ChildNode:=NextNode;
2160
ANode.Expanded:=HasVisibleChilds;
2161
ANode.MultiSelected:=FilterFits(ANode.Text,TheFilter);
2162
Result:=ANode.Expanded or ANode.MultiSelected;
2490
Result:=(ANode.Parent<>nil) and (ANode.GetFirstChild=nil)
2491
and (not FilterFits(ANode.Text,TheFilter));
2492
//debugln(['TCodeExplorerView.FilterNode "',ANode.Text,'" Parent=',ANode.Parent<>nil,' Child=',ANode.GetFirstChild<>nil,' Filter=',FilterFits(ANode.Text,TheFilter),' Result=',Result]);
2494
DeleteTVNode(ANode);
2165
function TCodeExplorerView.FilterFits(const NodeText, TheFilter: string
2497
function TCodeExplorerView.FilterFits(const NodeText, TheFilter: string): boolean;
2169
2500
PFilter: PChar;
2539
function TCodeExplorerView.GetCTNodePath(ACodeTool: TCodeTool;
2540
CodeNode: TCodeTreeNode): string;
2545
while CodeNode<>nil do begin
2547
case CodeNode.Desc of
2549
ctnTypeDefinition,ctnVarDefinition,ctnConstDefinition,ctnUseUnit:
2550
CurName:=ACodeTool.ExtractIdentifier(CodeNode.StartPos);
2553
CurName:=ACodeTool.ExtractDefinitionName(CodeNode);
2556
CurName:=ACodeTool.ExtractIdentifier(CodeNode.StartPos);
2559
CurName:=ACodeTool.ExtractProcName(CodeNode,[]);
2562
CurName:=ACodeTool.ExtractPropName(CodeNode,false); // property keyword is not needed because there are icons
2565
if CurName<>'' then begin
2566
if Result<>'' then Result:='.'+Result;
2567
Result:=CurName+Result;
2569
CodeNode:=CodeNode.Parent;
2573
procedure TCodeExplorerView.CreateNodePath(ACodeTool: TCodeTool;
2574
aNodeData: TObject);
2576
NodeData: TViewNodeData absolute aNodeData;
2577
AVLNode: TAvgLvlTreeNode;
2579
if NodeData.CTNode.Desc=ctnProcedure then
2580
NodeData.Path:=GetCTNodePath(ACodeTool,NodeData.CTNode);
2581
if NodeData.Path='' then exit;
2582
AVLNode:=fNodesWithPath.FindKey(NodeData,@CompareViewNodePaths);
2583
if AVLNode=nil then begin
2585
fNodesWithPath.Add(NodeData);
2588
// there is already a node with this path
2589
// => add params to distinguish overloads
2590
NodeData.CreateParams(ACodeTool);
2591
TViewNodeData(AVLNode.Data).CreateParams(ACodeTool);
2592
fNodesWithPath.Add(NodeData);
2595
procedure TCodeExplorerView.AddImplementationNode(ACodeTool: TCodeTool;
2596
CodeNode: TCodeTreeNode);
2598
NodeData: TViewNodeData;
2599
AVLNode: TAvgLvlTreeNode;
2600
DeclData: TViewNodeData;
2602
if (CodeNode.Desc=ctnProcedure)
2603
and ((ctnsForwardDeclaration and CodeNode.SubDesc)=0) then begin
2604
NodeData:=TViewNodeData.Create(CodeNode);
2606
NodeData.Path:=GetCTNodePath(ACodeTool,NodeData.CTNode);
2607
if NodeData.Path='' then exit;
2608
//debugln(['TCodeExplorerView.AddImplementationNode Proc=',NodeData.Path]);
2609
AVLNode:=fNodesWithPath.FindKey(NodeData,@CompareViewNodePaths);
2610
if (AVLNode=nil) or (TViewNodeData(AVLNode.Data).ImplementationNode<>nil)
2612
// there is no declaration, or there is already an implementation
2616
DeclData:=TViewNodeData(AVLNode.Data);
2617
if (DeclData.Params<>'') then begin
2618
// there are several nodes with this Path
2619
NodeData.CreateParams(ACodeTool);
2620
AVLNode:=fNodesWithPath.Find(NodeData);
2621
if (AVLNode=nil) or (TViewNodeData(AVLNode.Data).ImplementationNode<>nil)
2623
// there is no declaration, or there is already an implementation
2627
DeclData:=TViewNodeData(AVLNode.Data);
2629
// implementation found
2630
//debugln(['TCodeExplorerView.AddImplementationNode implementation found: ',NodeData.Path,'(',NodeData.Params,')']);
2631
NodeData.Desc:=CodeNode.Desc;
2632
NodeData.SubDesc:=CodeNode.SubDesc;
2633
NodeData.StartPos:=CodeNode.StartPos;
2634
NodeData.EndPos:=CodeNode.EndPos;
2635
DeclData.ImplementationNode:=NodeData;
2206
2643
function TCodeExplorerView.CompareCodeNodes(Node1, Node2: TTreeNode): integer;
2208
2645
SortDesc = AllIdentifierDefinitions+[ctnProcedure,ctnProperty];
2213
2650
ctnTypeSection,
2214
2651
ctnTypeDefinition,ctnGenericType:
2216
ctnVarSection,ctnConstSection,ctnResStrSection,ctnLabelSection,
2217
ctnVarDefinition,ctnConstDefinition,ctnProperty:
2653
ctnConstSection,ctnConstDefinition:
2655
ctnVarSection,ctnClassClassVar,ctnResStrSection,ctnLabelSection,
2219
2658
ctnInterface,ctnImplementation,ctnProgram,ctnPackage,ctnLibrary,
2222
2663
ctnUsesSection:
2225
2666
// class sections
2230
2668
ctnClassPrivate,
2231
2669
ctnClassProtected,
2232
2670
ctnClassPublic,
2233
ctnClassPublished : Result:=Desc-ctnClassConst;
2671
ctnClassPublished : Result:=Desc-ctnClassGUID;
2235
2673
else Result:=10000;