IDE: unit dependencies: overlays for cycles

git-svn-id: trunk@42884 -
This commit is contained in:
mattias 2013-09-19 18:23:56 +00:00
parent 5719113bb6
commit 999cc9e8e6
5 changed files with 116 additions and 110 deletions

View File

@ -9,7 +9,7 @@ object UnitDependenciesWindow: TUnitDependenciesWindow
OnCreate = FormCreate OnCreate = FormCreate
OnDestroy = FormDestroy OnDestroy = FormDestroy
Position = poScreenCenter Position = poScreenCenter
LCLVersion = '1.1' LCLVersion = '1.3'
object MainPageControl: TPageControl object MainPageControl: TPageControl
Left = 0 Left = 0
Height = 407 Height = 407
@ -218,7 +218,6 @@ object UnitDependenciesWindow: TUnitDependenciesWindow
ShowHint = True ShowHint = True
ShowRoot = False ShowRoot = False
TabOrder = 1 TabOrder = 1
OnAdvancedCustomDrawItem = AllUnitsTreeViewAdvancedCustomDrawItem
OnMouseDown = UnitsTreeViewMouseDown OnMouseDown = UnitsTreeViewMouseDown
OnSelectionChanged = AllUnitsTreeViewSelectionChanged OnSelectionChanged = AllUnitsTreeViewSelectionChanged
OnShowHint = UnitsTreeViewShowHint OnShowHint = UnitsTreeViewShowHint

View File

@ -68,6 +68,7 @@ type
public public
SCCNode: TUDSCCNode; SCCNode: TUDSCCNode;
function GetSCCNode: TUDSCCNode; function GetSCCNode: TUDSCCNode;
function HasImplementationUses: boolean;
destructor Destroy; override; destructor Destroy; override;
end; end;
@ -102,6 +103,9 @@ type
Identifier: string; // GroupName, Directory, Filename Identifier: string; // GroupName, Directory, Filename
Group: string; Group: string;
HasChildren: boolean; HasChildren: boolean;
IntfCycle: boolean;
ImplCycle: boolean;
HasImplementationUses: boolean;
end; end;
{ TUDNode } { TUDNode }
@ -178,9 +182,6 @@ type
procedure AllUnitsSearchPrevSpeedButtonClick(Sender: TObject); procedure AllUnitsSearchPrevSpeedButtonClick(Sender: TObject);
procedure AllUnitsShowDirsSpeedButtonClick(Sender: TObject); procedure AllUnitsShowDirsSpeedButtonClick(Sender: TObject);
procedure AllUnitsShowGroupNodesSpeedButtonClick(Sender: TObject); procedure AllUnitsShowGroupNodesSpeedButtonClick(Sender: TObject);
procedure AllUnitsTreeViewAdvancedCustomDrawItem(Sender: TCustomTreeView;
Node: TTreeNode; {%H-}State: TCustomDrawState; Stage: TCustomDrawStage;
var {%H-}PaintImages, {%H-}DefaultDraw: Boolean);
procedure RefreshButtonClick(Sender: TObject); procedure RefreshButtonClick(Sender: TObject);
procedure SelUnitsTreeViewExpanding(Sender: TObject; Node: TTreeNode; procedure SelUnitsTreeViewExpanding(Sender: TObject; Node: TTreeNode;
var AllowExpansion: Boolean); var AllowExpansion: Boolean);
@ -228,6 +229,8 @@ type
fImgIndexPackage: integer; fImgIndexPackage: integer;
fImgIndexDirectory: integer; fImgIndexDirectory: integer;
fImgIndexOverlayImplUses: integer; fImgIndexOverlayImplUses: integer;
fImgIndexOverlayIntfCycle: integer;
fImgIndexOverlayImplCycle: integer;
fAllUnitsTVSearchStartNode: TTreeNode; fAllUnitsTVSearchStartNode: TTreeNode;
fSelUnitsTVSearchStartNode: TTreeNode; fSelUnitsTVSearchStartNode: TTreeNode;
function CreateAllUnitsTree: TUDNode; function CreateAllUnitsTree: TUDNode;
@ -388,6 +391,17 @@ begin
Result:=SCCNode; Result:=SCCNode;
end; end;
function TUDUnit.HasImplementationUses: boolean;
var
i: Integer;
begin
Result:=false;
if UsesUnits=nil then exit;
for i:=0 to UsesUnits.Count-1 do
if TUDUses(UsesUnits[i]).InImplementation then
exit(true);
end;
destructor TUDUnit.Destroy; destructor TUDUnit.Destroy;
begin begin
FreeAndNil(SCCNode); FreeAndNil(SCCNode);
@ -541,6 +555,8 @@ begin
fImgIndexPackage := IDEImages.LoadImage(16, 'pkg_required'); fImgIndexPackage := IDEImages.LoadImage(16, 'pkg_required');
fImgIndexDirectory := IDEImages.LoadImage(16, 'pkg_files'); fImgIndexDirectory := IDEImages.LoadImage(16, 'pkg_files');
fImgIndexOverlayImplUses := IDEImages.LoadImage(16, 'pkg_core_overlay'); fImgIndexOverlayImplUses := IDEImages.LoadImage(16, 'pkg_core_overlay');
fImgIndexOverlayIntfCycle := IDEImages.LoadImage(16, 'ce_cycleinterface');
fImgIndexOverlayImplCycle := IDEImages.LoadImage(16, 'ce_cycleimplementation');
AllUnitsTreeView.Images:=IDEImages.Images_16; AllUnitsTreeView.Images:=IDEImages.Images_16;
SelUnitsTreeView.Images:=IDEImages.Images_16; SelUnitsTreeView.Images:=IDEImages.Images_16;
@ -601,40 +617,6 @@ begin
IdleConnected:=true; IdleConnected:=true;
end; end;
procedure TUnitDependenciesWindow.AllUnitsTreeViewAdvancedCustomDrawItem(
Sender: TCustomTreeView; Node: TTreeNode; State: TCustomDrawState;
Stage: TCustomDrawStage; var PaintImages, DefaultDraw: Boolean);
var
TV: TTreeView;
NodeRect: Classes.TRect;
x: Integer;
UDNode: TUDNode;
UGUnit: TUGUnit;
UsesImplCnt: Integer;
i: Integer;
y: Integer;
begin
if Stage<>cdPostPaint then exit;
TV:=Sender as TTreeView;
if not (TObject(Node.Data) is TUDNode) then exit;
UDNode:=TUDNode(Node.Data);
if UDNode.Typ<>udnUnit then exit;
UGUnit:=UsesGraph.GetUnit(UDNode.Identifier,false);
if UGUnit=nil then exit;
if (UGUnit.UsesUnits=nil) then exit;
UsesImplCnt:=0;
for i:=0 to UGUnit.UsesUnits.Count-1 do begin
if TUGUses(UGUnit.UsesUnits[i]).InImplementation then
inc(UsesImplCnt);
end;
if UsesImplCnt=0 then exit;
NodeRect:=Node.DisplayRect(False);
x:=Node.DisplayIconLeft+1;
y:=(NodeRect.Top+NodeRect.Bottom-TV.Images.Height) div 2;
TV.Images.Draw(TV.Canvas,x,y,fImgIndexOverlayImplUses);
end;
procedure TUnitDependenciesWindow.RefreshButtonClick(Sender: TObject); procedure TUnitDependenciesWindow.RefreshButtonClick(Sender: TObject);
begin begin
if udwParsing in FFlags then exit; if udwParsing in FFlags then exit;
@ -709,7 +691,7 @@ procedure TUnitDependenciesWindow.UnitsTreeViewShowHint(Sender: TObject;
ImplCnt:=0; ImplCnt:=0;
if List=nil then exit; if List=nil then exit;
for i:=0 to List.Count-1 do for i:=0 to List.Count-1 do
if TUGUses(List[i]).InImplementation then if TUDUses(List[i]).InImplementation then
inc(ImplCnt) inc(ImplCnt)
else else
inc(IntfCnt); inc(IntfCnt);
@ -1075,12 +1057,12 @@ begin
Filename:=AProject.Files[i].Filename; Filename:=AProject.Files[i].Filename;
CurUnit:=UsesGraph.GetUnit(Filename,false); CurUnit:=UsesGraph.GetUnit(Filename,false);
if CurUnit=nil then continue; if CurUnit=nil then continue;
if not (CurUnit is TUGGroupUnit) then begin if not (CurUnit is TUDUnit) then begin
debugln(['TUnitDependenciesDialog.CreateProjectGroup WARNING: ',CurUnit.Filename,' ',CurUnit.Classname,' should be TUGGroupUnit']); debugln(['TUnitDependenciesDialog.CreateProjectGroup WARNING: ',CurUnit.Filename,' ',CurUnit.Classname,' should be TUGGroupUnit']);
continue; continue;
end; end;
if TUGGroupUnit(CurUnit).Group<>nil then continue; if TUDUnit(CurUnit).Group<>nil then continue;
Result.AddUnit(TUGGroupUnit(CurUnit)); Result.AddUnit(TUDUnit(CurUnit));
end; end;
end; end;
@ -1100,9 +1082,9 @@ begin
for i:=0 to APackage.FileCount-1 do begin for i:=0 to APackage.FileCount-1 do begin
Filename:=APackage.Files[i].GetFullFilename; Filename:=APackage.Files[i].GetFullFilename;
CurUnit:=UsesGraph.GetUnit(Filename,false); CurUnit:=UsesGraph.GetUnit(Filename,false);
if CurUnit is TUGGroupUnit then begin if CurUnit is TUDUnit then begin
if TUGGroupUnit(CurUnit).Group<>nil then continue; if TUDUnit(CurUnit).Group<>nil then continue;
Result.AddUnit(TUGGroupUnit(CurUnit)); Result.AddUnit(TUDUnit(CurUnit));
end; end;
end; end;
end; end;
@ -1130,7 +1112,7 @@ procedure TUnitDependenciesWindow.CreateFPCSrcGroups;
var var
FPCSrcDir: String; FPCSrcDir: String;
Node: TAVLTreeNode; Node: TAVLTreeNode;
CurUnit: TUGGroupUnit; CurUnit: TUDUnit;
Directory: String; Directory: String;
Grp: TUGGroup; Grp: TUGGroup;
BaseDir: String; BaseDir: String;
@ -1142,9 +1124,9 @@ begin
// if in packages/<name>, put in group GroupPrefixFPCSrc+<name> // if in packages/<name>, put in group GroupPrefixFPCSrc+<name>
Node:=UsesGraph.FilesTree.FindLowest; Node:=UsesGraph.FilesTree.FindLowest;
while Node<>nil do begin while Node<>nil do begin
CurUnit:=TUGGroupUnit(Node.Data); CurUnit:=TUDUnit(Node.Data);
Node:=UsesGraph.FilesTree.FindSuccessor(Node); Node:=UsesGraph.FilesTree.FindSuccessor(Node);
if TUGGroupUnit(CurUnit).Group<>nil then continue; if TUDUnit(CurUnit).Group<>nil then continue;
if CompareFilenames(FPCSrcDir,LeftStr(CurUnit.Filename,length(FPCSrcDir)))<>0 if CompareFilenames(FPCSrcDir,LeftStr(CurUnit.Filename,length(FPCSrcDir)))<>0
then then
continue; continue;
@ -1160,14 +1142,14 @@ begin
if Grp.BaseDir='' then if Grp.BaseDir='' then
Grp.BaseDir:=BaseDir; Grp.BaseDir:=BaseDir;
//debugln(['TUnitDependenciesDialog.CreateFPCSrcGroups ',Grp.Name]); //debugln(['TUnitDependenciesDialog.CreateFPCSrcGroups ',Grp.Name]);
Grp.AddUnit(TUGGroupUnit(CurUnit)); Grp.AddUnit(TUDUnit(CurUnit));
end; end;
end; end;
procedure TUnitDependenciesWindow.GuessGroupOfUnits; procedure TUnitDependenciesWindow.GuessGroupOfUnits;
var var
Node: TAVLTreeNode; Node: TAVLTreeNode;
CurUnit: TUGGroupUnit; CurUnit: TUDUnit;
Filename: String; Filename: String;
Owners: TFPList; Owners: TFPList;
i: Integer; i: Integer;
@ -1179,7 +1161,7 @@ begin
LastDirectory:='.'; LastDirectory:='.';
Node:=UsesGraph.FilesTree.FindLowest; Node:=UsesGraph.FilesTree.FindLowest;
while Node<>nil do begin while Node<>nil do begin
CurUnit:=TUGGroupUnit(Node.Data); CurUnit:=TUDUnit(Node.Data);
if CurUnit.Group=nil then begin if CurUnit.Group=nil then begin
Filename:=CurUnit.Filename; Filename:=CurUnit.Filename;
//debugln(['TUnitDependenciesDialog.GuessGroupOfUnits no group for ',Filename]); //debugln(['TUnitDependenciesDialog.GuessGroupOfUnits no group for ',Filename]);
@ -1206,7 +1188,7 @@ begin
Group:=Groups.GetGroup(GroupNone,true); Group:=Groups.GetGroup(GroupNone,true);
//debugln(['TUnitDependenciesDialog.GuessGroupOfUnits ',Group.Name]); //debugln(['TUnitDependenciesDialog.GuessGroupOfUnits ',Group.Name]);
end; end;
Group.AddUnit(TUGGroupUnit(CurUnit)); Group.AddUnit(TUDUnit(CurUnit));
end; end;
Node:=UsesGraph.FilesTree.FindSuccessor(Node); Node:=UsesGraph.FilesTree.FindSuccessor(Node);
end; end;
@ -1377,7 +1359,7 @@ var
NodeText: String; NodeText: String;
RootNode: TUDNode; RootNode: TUDNode;
Filter: String; Filter: String;
UGUnit: TUGGroupUnit; UGUnit: TUDUnit;
AVLNode: TAVLTreeNode; AVLNode: TAVLTreeNode;
Group: TUGGroup; Group: TUGGroup;
GroupNode: TUDNode; GroupNode: TUDNode;
@ -1393,7 +1375,7 @@ begin
ShowDirectories:=AllUnitsShowDirsSpeedButton.Down; ShowDirectories:=AllUnitsShowDirsSpeedButton.Down;
RootNode:=TUDNode.Create; RootNode:=TUDNode.Create;
for AVLNode in UsesGraph.FilesTree do begin for AVLNode in UsesGraph.FilesTree do begin
UGUnit:=TUGGroupUnit(AVLNode.Data); UGUnit:=TUDUnit(AVLNode.Data);
Filename:=UGUnit.Filename; Filename:=UGUnit.Filename;
NodeText:=ExtractFileName(Filename); NodeText:=ExtractFileName(Filename);
if (Filter<>'') and (Pos(Filter, UTF8LowerCase(NodeText))<1) then if (Filter<>'') and (Pos(Filter, UTF8LowerCase(NodeText))<1) then
@ -1439,6 +1421,9 @@ begin
Node:=ParentNode.GetNode(udnUnit, NodeText, true); Node:=ParentNode.GetNode(udnUnit, NodeText, true);
Node.Identifier:=UGUnit.Filename; Node.Identifier:=UGUnit.Filename;
Node.Group:=GroupName; Node.Group:=GroupName;
Node.IntfCycle:=UGUnit.GetSCCNode.InIntfCycle;
Node.ImplCycle:=UGUnit.GetSCCNode.InImplCycle;
Node.HasImplementationUses:=UGUnit.HasImplementationUses;
end; end;
Result:=RootNode; Result:=RootNode;
end; end;
@ -1541,16 +1526,18 @@ procedure TUnitDependenciesWindow.AddUsesSubNodes(UDNode: TUDNode);
NodeTyp: TUDNodeType); NodeTyp: TUDNodeType);
var var
i: Integer; i: Integer;
UGUses: TUGUses; UGUses: TUDUses;
NodeText: String; NodeText: String;
SectionUDNode: TUDNode; SectionUDNode: TUDNode;
InImplementation: Boolean; InImplementation: Boolean;
UsedBy: Boolean; UsedBy: Boolean;
OtherUnit: TUGGroupUnit; OtherUnit: TUDUnit;
Filename: String; Filename: String;
UDNode: TUDNode; UDNode: TUDNode;
GroupName: String; GroupName: String;
Cnt: Integer; Cnt: Integer;
HasIntfCycle: Boolean;
HasImplCycle: Boolean;
begin begin
if ParentUDNode=nil then exit; if ParentUDNode=nil then exit;
if UsesList=nil then exit; if UsesList=nil then exit;
@ -1561,9 +1548,13 @@ procedure TUnitDependenciesWindow.AddUsesSubNodes(UDNode: TUDNode);
// count the number of uses // count the number of uses
Cnt:=0; Cnt:=0;
HasIntfCycle:=false;
HasImplCycle:=false;
for i:=0 to UsesList.Count-1 do begin for i:=0 to UsesList.Count-1 do begin
UGUses:=TUGUses(UsesList[i]); UGUses:=TUDUses(UsesList[i]);
if UGUses.InImplementation<>InImplementation then continue; if UGUses.InImplementation<>InImplementation then continue;
HasIntfCycle:=HasIntfCycle or UGUses.GetSCCNode.InIntfCycle;
HasImplCycle:=HasImplCycle or UGUses.GetSCCNode.InImplCycle;
inc(Cnt); inc(Cnt);
end; end;
if Cnt=0 then exit; if Cnt=0 then exit;
@ -1579,15 +1570,17 @@ procedure TUnitDependenciesWindow.AddUsesSubNodes(UDNode: TUDNode);
else exit; else exit;
end; end;
SectionUDNode:=ParentUDNode.GetNode(NodeTyp,NodeText,true); SectionUDNode:=ParentUDNode.GetNode(NodeTyp,NodeText,true);
SectionUDNode.IntfCycle:=HasIntfCycle;
SectionUDNode.ImplCycle:=HasImplCycle;
// create unit nodes // create unit nodes
for i:=0 to UsesList.Count-1 do begin for i:=0 to UsesList.Count-1 do begin
UGUses:=TUGUses(UsesList[i]); UGUses:=TUDUses(UsesList[i]);
if UGUses.InImplementation<>InImplementation then continue; if UGUses.InImplementation<>InImplementation then continue;
if UsedBy then if UsedBy then
OtherUnit:=TUGGroupUnit(UGUses.Owner) OtherUnit:=TUDUnit(UGUses.Owner)
else else
OtherUnit:=TUGGroupUnit(UGUses.UsesUnit); OtherUnit:=TUDUnit(UGUses.UsesUnit);
Filename:=OtherUnit.Filename; Filename:=OtherUnit.Filename;
NodeText:=ExtractFileName(Filename); NodeText:=ExtractFileName(Filename);
UDNode:=SectionUDNode.GetNode(udnUnit,NodeText,true); UDNode:=SectionUDNode.GetNode(udnUnit,NodeText,true);
@ -1600,16 +1593,18 @@ procedure TUnitDependenciesWindow.AddUsesSubNodes(UDNode: TUDNode);
UDNode.HasChildren:= UDNode.HasChildren:=
((OtherUnit.UsedByUnits<>nil) and (OtherUnit.UsedByUnits.Count>0)) ((OtherUnit.UsedByUnits<>nil) and (OtherUnit.UsedByUnits.Count>0))
or ((OtherUnit.UsesUnits<>nil) and (OtherUnit.UsesUnits.Count>0)); or ((OtherUnit.UsesUnits<>nil) and (OtherUnit.UsesUnits.Count>0));
UDNode.IntfCycle:=UGUses.GetSCCNode.InIntfCycle;
UDNode.ImplCycle:=UGUses.GetSCCNode.InImplCycle;
end; end;
end; end;
var var
Filename: String; Filename: String;
UGUnit: TUGGroupUnit; UGUnit: TUDUnit;
begin begin
// add connected units // add connected units
Filename:=UDNode.Identifier; Filename:=UDNode.Identifier;
UGUnit:=TUGGroupUnit(UsesGraph.GetUnit(Filename,false)); UGUnit:=TUDUnit(UsesGraph.GetUnit(Filename,false));
if UGUnit<>nil then begin if UGUnit<>nil then begin
AddUses(UDNode,UGUnit.UsesUnits,udnInterface); AddUses(UDNode,UGUnit.UsesUnits,udnInterface);
AddUses(UDNode,UGUnit.UsesUnits,udnImplementation); AddUses(UDNode,UGUnit.UsesUnits,udnImplementation);
@ -1855,8 +1850,8 @@ var
GroupObj: TObject; GroupObj: TObject;
GraphGroup: TLvlGraphNode; GraphGroup: TLvlGraphNode;
UnitNode: TAVLTreeNode; UnitNode: TAVLTreeNode;
GrpUnit: TUGGroupUnit; GrpUnit: TUDUnit;
UsedUnit: TUGGroupUnit; UsedUnit: TUDUnit;
begin begin
Exclude(FFlags,udwNeedUpdateGroupsLvlGraph); Exclude(FFlags,udwNeedUpdateGroupsLvlGraph);
GroupsLvlGraph.BeginUpdate; GroupsLvlGraph.BeginUpdate;
@ -1896,11 +1891,11 @@ begin
// add FPC source dependencies // add FPC source dependencies
UnitNode:=Group.Units.FindLowest; UnitNode:=Group.Units.FindLowest;
while UnitNode<>nil do begin while UnitNode<>nil do begin
GrpUnit:=TUGGroupUnit(UnitNode.Data); GrpUnit:=TUDUnit(UnitNode.Data);
UnitNode:=Group.Units.FindSuccessor(UnitNode); UnitNode:=Group.Units.FindSuccessor(UnitNode);
if GrpUnit.UsesUnits=nil then continue; if GrpUnit.UsesUnits=nil then continue;
for i:=0 to GrpUnit.UsesUnits.Count-1 do begin for i:=0 to GrpUnit.UsesUnits.Count-1 do begin
UsedUnit:=TUGGroupUnit(TUGUses(GrpUnit.UsesUnits[i]).UsesUnit); UsedUnit:=TUDUnit(TUDUses(GrpUnit.UsesUnits[i]).UsesUnit);
if (UsedUnit.Group=nil) or (UsedUnit.Group=Group) then continue; if (UsedUnit.Group=nil) or (UsedUnit.Group=Group) then continue;
Graph.GetEdge(GraphGroup,Graph.GetNode(UsedUnit.Group.Name,true),true); Graph.GetEdge(GraphGroup,Graph.GetNode(UsedUnit.Group.Name,true),true);
end; end;
@ -1922,15 +1917,15 @@ var
NewUnits: TFilenameToPointerTree; NewUnits: TFilenameToPointerTree;
UnitGroup: TUGGroup; UnitGroup: TUGGroup;
AVLNode: TAVLTreeNode; AVLNode: TAVLTreeNode;
GroupUnit: TUGGroupUnit; GroupUnit: TUDUnit;
i: Integer; i: Integer;
HasChanged: Boolean; HasChanged: Boolean;
Graph: TLvlGraph; Graph: TLvlGraph;
CurUses: TUGUses; CurUses: TUDUses;
SourceGraphNode: TLvlGraphNode; SourceGraphNode: TLvlGraphNode;
TargetGraphNode: TLvlGraphNode; TargetGraphNode: TLvlGraphNode;
NewGroups: TStringToPointerTree; NewGroups: TStringToPointerTree;
UsedUnit: TUGGroupUnit; UsedUnit: TUDUnit;
begin begin
Exclude(FFlags,udwNeedUpdateUnitsLvlGraph); Exclude(FFlags,udwNeedUpdateUnitsLvlGraph);
NewGroups:=TStringToPointerTree.Create(false); NewGroups:=TStringToPointerTree.Create(false);
@ -1944,7 +1939,7 @@ begin
NewGroups[UnitGroup.Name]:=UnitGroup; NewGroups[UnitGroup.Name]:=UnitGroup;
AVLNode:=UnitGroup.Units.FindLowest; AVLNode:=UnitGroup.Units.FindLowest;
while AVLNode<>nil do begin while AVLNode<>nil do begin
GroupUnit:=TUGGroupUnit(AVLNode.Data); GroupUnit:=TUDUnit(AVLNode.Data);
NewUnits[GroupUnit.Filename]:=GroupUnit; NewUnits[GroupUnit.Filename]:=GroupUnit;
AVLNode:=UnitGroup.Units.FindSuccessor(AVLNode); AVLNode:=UnitGroup.Units.FindSuccessor(AVLNode);
end; end;
@ -1958,7 +1953,7 @@ begin
i:=0; i:=0;
AVLNode:=NewUnits.Tree.FindLowest; AVLNode:=NewUnits.Tree.FindLowest;
while AVLNode<>nil do begin while AVLNode<>nil do begin
GroupUnit:=TUGGroupUnit(NewUnits.GetNodeData(AVLNode)^.Value); GroupUnit:=TUDUnit(NewUnits.GetNodeData(AVLNode)^.Value);
if (Graph.NodeCount<=i) or (Graph.Nodes[i].Data<>Pointer(GroupUnit)) then if (Graph.NodeCount<=i) or (Graph.Nodes[i].Data<>Pointer(GroupUnit)) then
begin begin
HasChanged:=true; HasChanged:=true;
@ -1975,13 +1970,13 @@ begin
Graph.Clear; Graph.Clear;
AVLNode:=NewUnits.Tree.FindLowest; AVLNode:=NewUnits.Tree.FindLowest;
while AVLNode<>nil do begin while AVLNode<>nil do begin
GroupUnit:=TUGGroupUnit(NewUnits.GetNodeData(AVLNode)^.Value); GroupUnit:=TUDUnit(NewUnits.GetNodeData(AVLNode)^.Value);
SourceGraphNode:=Graph.GetNode(UnitToCaption(GroupUnit),true); SourceGraphNode:=Graph.GetNode(UnitToCaption(GroupUnit),true);
SourceGraphNode.Data:=GroupUnit; SourceGraphNode.Data:=GroupUnit;
if GroupUnit.UsesUnits<>nil then begin if GroupUnit.UsesUnits<>nil then begin
for i:=0 to GroupUnit.UsesUnits.Count-1 do begin for i:=0 to GroupUnit.UsesUnits.Count-1 do begin
CurUses:=TUGUses(GroupUnit.UsesUnits[i]); CurUses:=TUDUses(GroupUnit.UsesUnits[i]);
UsedUnit:=TUGGroupUnit(CurUses.UsesUnit); UsedUnit:=TUDUnit(CurUses.UsesUnit);
if UsedUnit.Group=nil then continue; if UsedUnit.Group=nil then continue;
if not NewGroups.Contains(UsedUnit.Group.Name) then continue; if not NewGroups.Contains(UsedUnit.Group.Name) then continue;
TargetGraphNode:=Graph.GetNode(UnitToCaption(UsedUnit),true); TargetGraphNode:=Graph.GetNode(UnitToCaption(UsedUnit),true);
@ -2016,6 +2011,14 @@ begin
TVNode.ImageIndex:=GetImgIndex(UDNode); TVNode.ImageIndex:=GetImgIndex(UDNode);
TVNode.SelectedIndex:=TVNode.ImageIndex; TVNode.SelectedIndex:=TVNode.ImageIndex;
TVNode.HasChildren:=UDNode.HasChildren; TVNode.HasChildren:=UDNode.HasChildren;
if UDNode.IntfCycle then
TVNode.OverlayIndex:=fImgIndexOverlayIntfCycle
else if UDNode.ImplCycle then
TVNode.OverlayIndex:=fImgIndexOverlayImplCycle
else if UDNode.HasImplementationUses then
TVNode.OverlayIndex:=fImgIndexOverlayImplUses;
//if TVNode.OverlayIndex>=0 then
// debugln(['TUnitDependenciesWindow.CreateTVNodes ',TVNode.Text,' Overlay=',TVNode.OverlayIndex,' ',TV.Images.Count]);
CreateTVNodes(TV,TVNode,UDNode,Expand); CreateTVNodes(TV,TVNode,UDNode,Expand);
TVNode.Expanded:=Expand and (TVNode.Count>0); TVNode.Expanded:=Expand and (TVNode.Count>0);
AVLNode:=ParentUDNode.ChildNodes.FindSuccessor(AVLNode); AVLNode:=ParentUDNode.ChildNodes.FindSuccessor(AVLNode);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 530 B

After

Width:  |  Height:  |  Size: 562 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 345 B

After

Width:  |  Height:  |  Size: 403 B

View File

@ -9362,43 +9362,47 @@ LazarusResources.Add('ce_variable','PNG',[
+#218#0#0#0#0'IEND'#174'B`'#130 +#218#0#0#0#0'IEND'#174'B`'#130
]); ]);
LazarusResources.Add('ce_cycleinterface','PNG',[ LazarusResources.Add('ce_cycleinterface','PNG',[
#137'PNG'#13#10#26#10#0#0#0#13'IHDR'#0#0#0#12#0#0#0#12#8#2#0#0#0#217#23#203 #137'PNG'#13#10#26#10#0#0#0#13'IHDR'#0#0#0#21#0#0#0#16#8#6#0#0#0#249#218'4%'#0
+#176#0#0#0#6'tRNS'#0#0#0#0#0#0'n'#166#7#145#0#0#0#9'pHYs'#0#0#15'a'#0#0#15'a' +#0#0#6'bKGD'#0#255#0#255#0#255#160#189#167#147#0#0#0#9'pHYs'#0#0#15'a'#0#0#15
+#1#168'?'#167'i'#0#0#0#249'IDATx'#218#141#144'?O'#194#0#16#197#127#252'[j'#24 +'a'#1#168'?'#167'i'#0#0#0#7'tIME'#7#221#9#19#17'6'#3' 96'#217#0#0#1' IDAT8'
+'@pA\'#4#26'%'#198#164#196#133#129#15'@'#2'qq1q'#128#205#207#0#11'+CG'#190 +#203#237#146#175'K'#3'q'#24#135#159#155'[9'#153#226#156#6#181#185'Y'#134#229
+#130#3#155'2'#146#16'w:'#18'V'#195'$'#132't'#209#210'BI'#207#193#208'4'#136#9 +#166'ea'#127#192'@'#177'X'#4#131'3'#249'7'#204'b5\'#20#147#213'`'#212'('#12
+'7'#221#189'{'#247'^'#238#193#17#21#9#14'%'#168#195'-'#184#176#8#224'!'#191 +#171'xMY1'#136'A'#28#140'3'#200'y'#231#221#216#199'"'#243#7'+'#223'1'#155'O|'
+'3@KT'#201#221#224'n'#153#140#223#220#247#250#158#146#1'Z'#177#131'z'#205#183 +'y'#223#135#247#229#243#194#31'`'#253'.'#148'A+@'#2'\'#3#183#3'z'#140#164#30
+#133#235#145#189'Rm'#245#194#25#191#250#26'w '#233'G'#185#127#145'|s'#132'2 ' +#200#153#170'Aa'#25#146'.'#220#221'p'#158'\'#177'n('#182'~'#8'K'#7'07'#1#157
+'&'#153#170#228'ZB'#254#220''''#245'9'#145'pI'#162#197#143#157'{'#159#144#164 +'6'#196#9#216#147'p'#255#196#201#203'1'#187#166#27#175#130'4'#179'%m'#156'J'
+#154#18#175#149#1#136#2#15'Xx'#6#30#237#221#153#133#176#178#144#181#189#247 +#197#186#154#216#186' #'#205#215#164'BC'#162#168#5#144#145#244#140'q)U'#150
+#167#14#194#169#6'C'#16#165'"'#225#167'O'#146')_'#9#232#193's'#164#204#153'f' +#210'%=`'#233#171'nI'#249#186#148']S'#197'@'#154#6#216'$'#176#232'y'#208#131
+#216'361'#182'q'#152#234#152#203' i'#243'kb'#127#225'88'#230#156#145#142#217 +#253'o'#195#1#130#183#0#244'N8'#236'+'#184' 1-'#7't'#9#146']'#149'R'#219'z&'
+#253#27'k'#11#4'*p'#9#201#255#178'W'#160#1#133'C'#171#31'm'#151'P '#212#169 +#167#188#233#166#0'G'#160#189#177#10#204':x'#225'#'#196#25#232'f'#129#22'.>'
+#164#214#0#0#0#0'IEND'#174'B`'#130 +#29#131#160#250#210#248#243'`'#194'W'#136'"'#136'|'#218'4q'#241'9'#28#226'W'
+#251'4@'#2'UA'#139#160#156'i'#226#131#176'A;'#160#165'Q'#200#254#25')'#31'`#'
+'wi'#169#23'8'#152#0#0#0#0'IEND'#174'B`'#130
]); ]);
LazarusResources.Add('ce_cycleimplementation','PNG',[ LazarusResources.Add('ce_cycleimplementation','PNG',[
#137'PNG'#13#10#26#10#0#0#0#13'IHDR'#0#0#0#12#0#0#0#12#8#6#0#0#0'Vu\'#231#0#0 #137'PNG'#13#10#26#10#0#0#0#13'IHDR'#0#0#0#16#0#0#0#16#8#6#0#0#0#31#243#255'a'
+#0#9'pHYs'#0#0#11#19#0#0#11#19#1#0#154#156#24#0#0#0#7'tIME'#7#221#9#15#15#26 +#0#0#0#6'bKGD'#0#255#0#255#0#255#160#189#167#147#0#0#0#9'pHYs'#0#0#11#19#0#0
+#20#150#172#190#237#0#0#1#177'IDAT('#207#149#146'?h'#19'a'#0#197#127#247'}' +#11#19#1#0#154#156#24#0#0#0#7'tIME'#7#221#9#19#17'5'#31#31#21'9U'#0#0#1#191
+#151#139'I'#233#162'CD*URR'#132#182#161'EZ'#11#130#161#10#1'M'#160#187#136'T' +'IDAT8'#203#237#146'=hSQ'#24#134#159'{'#206#189#137'I'#233#162'CD*URR'#132
+''']'#28#20#20'BAp'#209'E'#231' X'#187#138'[T('#136'E4'#189'D'#169'1'#127#170 +#182#161'EZ'#11#130#161#10#1'M'#160#187#136'T'']'#28#20','#132#130#224#162
+'P'#10#157';'#152#164'&6'#189#203'}'#247'9'#180')tp'#240#205#239#7#143#247#30 +#139#206'A'#176'v'#21#183#168'P'#16#139'h'#154'D'#169'1?U('#133#206#29'LR'#19
+#252#167#12#128'J2'#201#216#210#18#0#139#207#195#233'_u='#222#233'h'#128'R' +#155#222#228#158'{'#28'l'#22#155#22#193#213'wz'#135#239'{'#248'~^'#248'G'#25
+#230#225'n'#14#224#237#200#8'Wj'#181'='#0'`{kL'#188'z'#189#241'a8&'#166#143 +#0#197'h'#148#145#197'E'#0#22#158#248#227#223'+z'#180#217#212#0#249#196#189
+#29#21#150#167'4'#155#155#190#187'R'#240#236#248#168#156#185'zc'#199#7#144'=' +#157#20#192#171#161'!.'#149#203#221#1#0'['#155'#'#226#249#139#245#183#131'!1'
+' z'#186#181'<'#20#21#23#6'O'#10#217'q4]'#23'"'#17'!'#209#156#202#23'T'#226 +'y'#228#176#240'8J'#179#177#225#182#150#179'N&<,'#167'._'#219'v'#187'M ;&x'
+#235#170'zy'#0',d'#195#233#248#168#188'{fX'#202#234#154'O'#222'V'#229#218#15 +#178#190'4'#16#20#231#250#143#11#217#180'5'#237#22#4#2'B'#162'9'#145#206#170
+#181'%$'#199'cC'#146'v['#159#136'DD'#185'\Q'#235'&'#128#239'sn'#245#187#178 +#200#167#21#245'l_'#192'|'#210#31#15#15#203#219#167#6#165','#173#186#164'3'
+#222'/{4'#154'~'#169#213'"'#181#253'['#203'FS'#231'B'#161'@<'#26#21#214'g' +#170'P'#254#170'6'#133#228'hh@'#210'h'#232'c'#129#128'('#20#138'j'#237'O'#128
+#219#27#7'r'#230#183#169')&n'#21'3@'#6#224#222#157#224#139'p'#136'@'#189#174 +#9#224#186#156'Y'#249#162'<o'#150#28#170'57_'#175#19#219#250#161'e'#181#166
+#165#227#128#242'4'#237'?'#176'_'#2'b'#162'X'#228#233#147#144#1'0'#255#224'H' +'S>'#159#21#14#6#133#231'C'#198#25#5'R{'#0#159'''&'#24#187#145'K'#0#9#128';'
+#22#152'['#223#240'o'#247#247#27#249#201#179'f'#220#16#176#246'S'#185#134'0J' +#183#188'O'#253'>'#172'JEK'#219#6#229'h'#26'?a'#247#168'{$'#198'r9'#30'='#244
+#7#181#238#155'?'#245#245#25#231#167'''%'#141#166#198'S'#16#12'B'#165#170#176 +#25#0's'#179#135#146#192#204#218#186'{'#179#183#215'H'#143#159'6'#195#134#128
+#191#168#143'o'#222'u'#19#0'f'#15'p'#187#26#211#129']'#7'v:'#224'8'#154'R' +#213'o'#170'e'#8'#'#191#239#27'w'#155#223#247#244#24'g'''#199'%'#213#154#198
+#217'w'#171'5e'#175#20#188#153'C'#235'=~'#180#23#233#230'u+;w'#205#210#201'K' +'Q'#224#245'B'#177#164#200'|T'#239'^'#190'nG'#186#1#204#142'i'#181'5'#166#13
+#230#179#139#9's>u9'#144#234'y'#238#15#12#28#158'|!'#22#3'`6'#29'X'#156'M'#7 +';6l7'#193#182'5'#249#130#219'*'#149'Uf9'#235'L'#29#152#166#7#247#127#175'p'
+#6#255'u'#141#191'O'#19#174#10'H'#217#228'^'#0#0#0#0'IEND'#174'B`'#130 +#253#170'''9s'#197#163#163#23#204#199#231'#'#230'\'#236#162#21#235#212#220
+#237#235';8'#146#243#161#16#0#211'qka:n'#245#243'_'#127#173'_'#161'2'#174#10
+#11#198'x'#150#0#0#0#0'IEND'#174'B`'#130
]); ]);
LazarusResources.Add('show_source','PNG',[ LazarusResources.Add('show_source','PNG',[
#137'PNG'#13#10#26#10#0#0#0#13'IHDR'#0#0#0#16#0#0#0#16#8#6#0#0#0#31#243#255'a' #137'PNG'#13#10#26#10#0#0#0#13'IHDR'#0#0#0#16#0#0#0#16#8#6#0#0#0#31#243#255'a'